how to create select join multiple condition in laravel 5.3 - laravel

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();

Related

Laravel eloquent orwhere in leftjoin fails

My eloquent query is not giving me what I expects. When I use orWhere it is put on the end of the query not after the leftjoin.
$r = groupofpupil::where('group_id' , '=', '13')
->leftjoin('pupils' ,'pupil1_id' , '=', 'pu_id' )
->orWhere('pupil0_id', '=', 'pu_id')
->leftjoin('users', 'pupils.id', '=', 'users.id')
->select('*')
->get();
the sql query is:
SELECT * from groupofpupils
LEFT JOIN pupils on pupil1_id = pu_id
LEFT JOIN users on pupils.id = users.id
WHERE group_id = 13
OR pupil0_id = pu_id
but I expected this
SELECT * from groupofpupils
LEFT JOIN pupils on pu_id = pupil1_id OR pu_id = pupil0_id
LEFT JOIN users on pupils.id = users.id
WHERE group_id = 13
Please, what am I doing wrong?
Try something like this :
$r = groupofpupil::leftjoin('pupils', 'pupils.pupil1_id', '=', 'groupofpupils.pu_id')
->leftjoin('users', 'users.id', '=', 'pupils.id')
->where('groupofpupils.group_id', 13)
->orWhere('pupils.pupil0_id', '=', 'groupofpupils.pu_id')
->get();

subquery inside orWhere in laravel

I need assistance to build up the query like below in laravel:
SELECT *
FROM table t
WHERE t.a = 1
OR (t.a=0
AND t.id IN (
SELECT o.a_id
FROM other_table o
WHERE o.x > 3
)
);
You could try to build your exact current query, and in fact it might even be the most efficient to write it. But, if we rephrase your query using a left join, it becomes somewhat easier to express in Laravel code.
SELECT *
FROM your_table t
LEFT JOIN other_table o
ON t.id = o.a_id AND o.x > 3
WHERE
t.a = 1 OR
(t.a = 0 AND o.a_id IS NOT NULL);
This would translate to the following Laravel code:
$result = DB::table('your_table t')
->leftJoin('other_table o', function($join) {
$join->on('t.id', '=', 'o.a_id');
$join->on('o.x', '>', '3');
})
->where('t.a', '=', '1')
->orWhere(function($query) {
return $query->where('t.a', '=', '0')
->whereNotNull('o.a_id')
})
->get();

Lumen eloquent left join

I want to make some migration from Laravel to Lumen, before that every code on my Laravel working and has no error and running well. Then i found this line and eloquent in Lumen translate this different than Laravel.
DB::table('products_categories')
->select('products.*', 'brands.name as brand_name', 'categories.link_rewrite as category_link_rewrite',
'product_medias.id as id_image', 'product_stocks.quantity as product_stock', 'product_medias.path','product_medias.filename', 'specific_prices.reduction_type', 'specific_prices.reduction as reduction',
'specific_prices.reduction', 'products_categories.position')
->leftJoin('products', 'products.id', '=', 'products_categories.product_id')
->leftJoin('product_stocks', 'products.id', '=', 'product_stocks.product_id')
->leftJoin('brands', 'brands.id', '=', 'products.brand_id')
->leftjoin('product_medias', function($join){
$join->on('product_medias.product_id', '=', 'products.id')
->whereIn('product_medias.cover', [1, 0]);
})
->leftJoin('categories', 'products_categories.category_id', '=', 'categories.id')
->leftJoin('specific_prices', function($join){
$join->on('specific_prices.product_id', '=', 'products.id')
->on(DB::raw("(`specific_prices`.`from` = '0000-00-00 00:00:00' OR '".date('Y-m-d H:i:s')."' >= `specific_prices`.`from`)"), DB::raw(''), DB::raw(''));
})
->where('categories.name','=', "Special Price" )
->where('products.active','=', 1)
->whereNull('products.deleted_at')
->groupBy('products_categories.product_id')
->orderBy('products_categories.id', 'desc');
Once again it's working on my Laravel but i get 'Error' on Lumen, is there any solution to solve this?
If i dump this line the query will look like this :
select `products`.*, `brands`.`name` as `brand_name`, `categories`.`link_rewrite` as `category_link_rewrite`, `product_medias`.`id` as `id_image`, `product_stocks`.`quantity` as `product_stock`, `product_medias`.`path`, `product_medias`.`filename`, `specific_prices`.`reduction_type`, `specific_prices`.`reduction` as `reduction`, `specific_prices`.`reduction`, `products_categories`.`position` from `products_categories` left join `products` on `products`.`id` = `products_categories`.`product_id` left join `product_stocks` on `products`.`id` = `product_stocks`.`product_id` left join `brands` on `brands`.`id` = `products`.`brand_id` left join `product_medias` on `product_medias`.`product_id` = `products`.`id` and `product_medias`.`cover` in (1, 0) left join `categories` on `products_categories`.`category_id` = `categories`.`id` left join `specific_prices` on `specific_prices`.`product_id` = `products`.`id` and (`specific_prices`.`from` = '0000-00-00 00:00:00' OR '2016-11-14 09:12:44' >= `specific_prices`.`from`) = where `categories`.`name` = Special Price and `products`.`active` = 1 and `products`.`deleted_at` is null group by `products_categories`.`product_id` order by `products_categories`.`id` desc limit 10
There is equal symbol after left join specific_prices and also didn't track 'Special Price' as character

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")

Laravel: change a raw query in a "query-builder" or "eloquent" one

I have this Laravel Query Builder snippet that is working fine:
$records = DB::table('users')
->select(
DB::raw('users.*, activations.id AS activation,
(SELECT roles.name FROM roles
INNER JOIN role_users
ON roles.id = role_users.role_id
WHERE users.id = role_users.user_id LIMIT 1)
AS role')
)
->leftJoin('activations', 'users.id', '=', 'activations.user_id')
->where('users.id', '<>', 1)
->orderBy('last_name')
->orderBy('first_name')
->paginate(10);
Is there a way to avoid use of raw queries and get the same result? In other words, how can I write this in a more "query-builder" style? Can I also translate this into an Eloquent query?
Thanks
You can used selectSub method for your query.
(1) First create the role query
$role = DB::table('roles')
->select('roles.name')
->join('roles_users', 'roles.id', '=', 'role_users.role_id')
->whereRaw('users.id = role_users.user_id')
->take(1);
(2) Second added the $role sub query as role
DB::table('users')
->select('users.*', 'activations.id AS activation')
->selectSub($role, 'role') // Role Sub Query As role
->leftJoin('activations', 'users.id', '=', 'activations.user_id')
->where('users.id', '<>', 1)
->orderBy('last_name')
->orderBy('first_name')
->paginate(10);
Output SQL Syntax
"select `users`.*, `activations`.`id` as `activation`,
(select `roles`.`name` from `roles` inner join `roles_users` on `roles`.`id` = `role_users`.`role_id`
where users.id = role_users.user_id limit 1) as `role`
from `users`
left join `activations` on `users`.`id` = `activations`.`user_id`
where `users`.`id` <> ?
order by `last_name` asc, `first_name` asc
limit 10 offset 0"

Resources