sql to query builder laravel 4 with multiple table select - laravel-4

I would like to translate this sql request in query builder for laravel 4.2, could you help me?
Thanks in advance!
Table api_calls => id | key_id | server | created_at
Table api_key => id | key | created_at
SQL :
SELECT K.key FROM api_key as K
WHERE
(SELECT count(id) FROM api_calls WHERE server = $server AND key_id = K.id AND created_at >= $DateSeconds) < 10
AND
(SELECT count(id) FROM api_calls WHERE server = $server AND key_id = K.id AND created_at >= $DateMinutes) < 500
GROUP BY K.key

Use joins ang aggregation like that:
DB::table('api_key as K')
->select('K.*')
->join('api_calls as ac1', function ($join) use ($server, $DateSeconds) {
$join->on('ac1.server', '=', DB::raw($server));
$join->on('ac1.key_id', '=', 'K.id');
$join->on('ac1.created_at', '>=', DB::raw($DateSeconds));
})
->join('api_calls as ac2', function ($join) use ($server, $DateMinutes) {
$join->on('ac2.server', '=', DB::raw($server));
$join->on('ac2.key_id', '=', 'K.id');
$join->on('ac2.created_at', '>=', DB::raw($DateMinutes));
})
->having(DB::raw('COUNT(ac1.id)'), '<', 10)
->having(DB::raw('COUNT(ac2.id)'), '<', 500)
->groupBy('K.id')
->get();

Related

Nested Select in Eloquent

I want to recreate below SQL in Eloquent (Laravel 6 LTS)
I want to avoid DB::raw as I have logics behind the PartnerPrice::class (model)
SELECT *
FROM (SELECT *,
ROW_NUMBER ()
OVER (PARTITION BY group, TYPE
ORDER BY effective_at DESC, created_at DESC)
r
FROM partner_prices
WHERE group = 'premier'
and partner_id = 8
AND TYPE = 'premium'
AND effective_at <= '2020-10-31') a
WHERE r = 1
ORDER BY group;
Here's my working inner query.
I just need help wrapping this with another select and add a where('r', 1)
$sub = PartnerPrice::select('*')
->selectRaw('ROW_NUMBER () OVER (PARTITION BY mccmnc, TYPE ORDER BY effective_at DESC, created_at DESC) r')
->where('type', $type)
->where('partner_id', $partnerId)
->where('group', $group)
->where('effective_at', '<=', now()->subMonth()->lastOfMonth())
->get();
You could use the toSql method with mergeBindings like this
$queryBuilder = PartnerPrice::select('*')
->selectRaw('ROW_NUMBER () OVER (PARTITION BY mccmnc, TYPE ORDER BY effective_at DESC, created_at DESC) r')
->where('type', $type)
->where('partner_id', $partnerId)
->where('group', $group)
->where('effective_at', '<=', now()->subMonth()->lastOfMonth());
$result = DB::table(DB::raw('(' . $queryBuilder->toSql() . ') as a'))
->mergeBindings($queryBuilder->getQuery())
->where('a.r', 1)
->get();
Note that I omitted the get() on the first builder
Also I think you can use
DB::select('*')
->fromSub($queryBuilder, 'a')
->where('a.r', 1)
->get();
But never used it. try this too.

Laravel having query

This is my query:
Order::query()
->join('dispatcher_contractor_pays', function ($join) {
$join->on('orders.id', '=', 'dispatcher_contractor_pays.order_id')
->where('dispatcher_contractor_pays.contractor_type', '=', Contractor::class);
})
->join('order_workers_value_added', function ($join) {
$join->on('orders.id', '=', 'order_workers_value_added.order_id')
->where('order_workers_value_added.worker_type', '=', Contractor::class);
})
->having('orders.amount', '>', DB::raw('SUM(order_workers_value_added.amount)
+ SUM(dispatcher_contractor_pays.sum)'));
And get error:
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'orders.amount' in 'having clause' (SQL: select count(*) as aggregate from `orders` inner join `dispatcher_contractor_pays` on `orders`.`id` = `dispatcher_contractor_pays`.`order_id` and `dispatcher_contractor_pays`.`contractor_type` = Modules\Dispatcher\Entities\Directories\Contractor inner join `order_workers_value_added` on `orders`.`id` = `order_workers_value_added`.`order_id` and `order_workers_value_added`.`worker_type` = Modules\Dispatcher\Entities\Directories\Contractor where `status` not in (open) and `orders`.`contractor_id` = 13 and `domain_id` = 1 and exists (select * from `dispatcher_contractors` inner join `order_workers` on `dispatcher_contractors`.`id` = `order_workers`.`worker_id` where `orders`.`id` = `order_workers`.`order_id` and `order_workers`.`worker_type` = Modules\Dispatcher\Entities\Directories\Contractor and `dispatcher_contractors`.`deleted_at` is null) and `orders`.`deleted_at` is null having `orders`.`amount` > SUM(order_workers_value_added.amount) + SUM(dispatcher_contractor_pays.sum))"
What am I doing wrong?
Tables structure
orders : |id,amount,status, e.t.c |
dispatcher_contractor_pays: |id,date,sum,order_id,contractor_type, e.t.c |
order_workers_value_added: |id,amount,order_id,worker_type,worker_id, e.t.c |

I Create mysql query but i not get pagination how to use laravel paginate in this query

I've created MySQL query for searching results. The query works properly but if I use laravel pagination on this query I get an error
Call to a member function paginate() on array ,
How to solve this with pagination?
$search = \DB::SELECT("SELECT l.*,
r.id AS reservation_id,
r.status AS res_status,
r.start_date,
r.end_date,
Avg(r.rating) AS rating
FROM listings l
LEFT JOIN reservations r ON r.listing_id = l.id
WHERE ( ( Cast('" . $search_date . "' AS date) NOT BETWEEN r.start_date AND r.end_date ) OR r.status = 'Cancel' )
AND l.city_id = $city_id
AND l.persons >= $guests
AND l.listing_type_id = $type
GROUP BY l.id
ORDER BY r.rating DESC
");
DB::select() will return an array. You could probably convert your query to a Query Builder and then use paginate() on it. For example:
$search = DB::table('listings')
->selectRaw('listings.*, reservations.id AS reservation_id, reservations.status AS res_status, reservations.start_date, reservations.end_date, AVG(reservations.rating) as rating')
->leftJoin('reservations', 'reservations.listing_id', 'listings.id')
->whereRaw("(CAST(? AS date) NOT BETWEEN reservations.start_date AND reservations.end_date) or reservations.status = 'Cancel'", [$search_date])
->where('listings.city_id', '=', $city_id)
->where('listings.persons', '>=', $guests)
->where('listings.listing_type_id', '=', $type)
->groupBy('listings.id')
->orderBy('reservations.rating', 'DESC')
->paginate(10);

how to create select join multiple condition in laravel 5.3

how to create select join multiple condition in laravel 5.3
SQL SELECT Statement.
SELECT table_1.column_1
,table_2.column_1
,table_3.column_1
FROM table_1
LEFT JOIN table_2
ON table_1.column_1 = table_2.column_1
LEFT JOIN table_3
ON table_1.column_2 = table_3.column_2
AND table_3.column_3 <= NOW()
AND ( table_3.column_4 >= NOW()
OR table_3.column_4 = 0
)
WHERE table_1.column_1 = '0000000001'
I want to convert SQL Statement to laravel select.
I try.
$result = DB::table('table_1')
->select('table_1.column_1', 'table_2.column_1', 'table_3.column_1')
->leftJoin('table_1', 'table_1.column_1', '=', 'table_2.column_1')
->leftJoin('table_3', 'table_1.column_2', '=', 'table_3.column_2')
->where('table_1', $_POST['id'])
->get();
DB::table('table_1')
->select('table_1.column_1', 'table_2.column_1', 'table_3.column_1')
->leftJoin('table_1', 'table_1.column_1', '=', 'table_2.column_1')
->leftJoin('table_3', 'table_1.column_2', '=', 'table_3.column_2')
->where('table_1.column_1', $_POST['id'])
->where('table_3.column_3','>=', NOW())
->where(function($query) {
$query->where('table_3.column_4', '>=', NOW())
->orWhere('table_3.column_4','0');
})
->get();

Query builder isn't execute where = on another column

Sorry, my question title isn't very clear but I couldn't figure a way to word this question.
I have the following query builder code.
return self::select(DB::raw('sum(user_points.points) AS points, users.id AS user_id, users.username, users.avatar, users.firstname, users.lastname'))
->join('users', 'users.id', '=', 'user_points.user_id')
$query->where('user_points.artist_id', 0)->orWhere('user_points.artist_id', 'users.favourite_artist_id');
})
->where('user_points.created_at', '>=', $startDate)
->where('user_points.created_at', '<=', $endDate)
->groupBy('users.id')
->orderBy('points', 'DESC')
->orderBy('user_id', 'ASC')
->simplePaginate(100);
It runs ok but is ignore the inner where query, specifically it's ignoring part of this;
$query->where('user_points.artist_id', 0)->orWhere('user_points.artist_id', 'users.favourite_artist_id');
})
It's matching 'user_points.artist_id = 0', but it's not matching the 'user_points.artist_id = users.favourite_artist_id', presumable it's got something to do with the way it's handling the bindings? But I can't seem to find a way to get it to work.
The complete query should end up like this;
SELECT SUM(user_points.points) AS points, users.id AS user_id, users.username, users.avatar, users.firstname, users.lastname
FROM user_points
INNER JOIN users ON users.id = user_points.user_id
WHERE (user_points.artist_id = 0 OR user_points.artist_id = users.favourite_artist_id)
AND user_points.created_at >= '$startDate' AND user_points.created_at <= '$endDate'
GROUP BY user_id
ORDER BY points DESC, user_id ASC
I updated the query builder code to this.
return self::select(DB::raw('sum(user_points.points) AS points, users.id AS user_id, users.username, users.avatar, users.firstname, users.lastname'))
->join('users', 'users.id', '=', 'user_points.user_id')
->where(function($query) {
$query->Where('user_points.artist_id', 0)->orWhere(DB::raw('user_points.artist_id = users.favourite_artist_id'));
})
->where('user_points.created_at', '>=', $startDate)
->where('user_points.created_at', '<=', $endDate)
->groupBy('users.id')
->orderBy('points', 'DESC')
->orderBy('user_id', 'ASC')
->simplePaginate(100);
That didn't work as the final query ended up looking like this.
select sum(user_points.points) AS points, users.id AS user_id, users.username, users.avatar, users.firstname, users.lastname
from `user_points` inner join `users` on `users`.`id` = `user_points`.`user_id` where (`user_points`.`artist_id` = ? or user_points.artist_id = users.favourite_artist_id is null)
and `user_points`.`created_at` >= ?
and `user_points`.`created_at` <= ?
group by `users`.`id`
order by `points` desc, `user_id` asc
You need to add the second where (or) as a raw query. The where method will add the second column as a value so you are actually trying the following:
user_points.artist_id = 'users.favourite_artist_id'
Try the following:
whereRaw("user_points.artist_id = users.favourite_artist_id")

Resources