Laravel Eloquent ORM query - php

I have been trying this mysql query to convert into laravel query but I am unable to figure it out.
SELECT max(a.date) as max FROM table1 a, table2 b where
a.publishing_time<='2015-02-27 12:30:00' and a.Status='1' and
a.id=b.table1_id
table 1 fields are:-
sl | date | publishing_time | status
table 2 fields are
sl | table1_id | additional_fields
I am stucked on this please help me

Try this Laravel query
DB::table('table1 as a')
->select(DB::raw('max(a.date) as max_date'))
->join('table 2 as b', 'a.id', '=', 'b.table1_id')
->where('a.publishing_time'<='2015-02-27 12:30:00')
->where(Status='1')
->get();

Try this..
This is laravel join query
$resource = DB::table('table1')->join('table2', 'table1.id', '=', 'table2.table1_id')->where('table1.publishing_time','<=','2015-02-27 12:30:00')->where('table1.Status','1');

Try something like:
DB::table('table a as a')->join('table b as b', 'a.id', '=', 'b.table1_id')->max('a.data as max')->where('a.publishing_time', '<=', '2015-02-27 12:30:00')->where('a.status', 1)->get();

Related

Using eloquent how to get all records of a many to many relationship that the max value in their pivot table

I want to select a specific record from table a and all their latest records from table a_b that has relation with table b before a specific date. For example
Table (a)
id
name
1
aa
Table (b)
id
name
1
b1
2
b2
3
b3
4
b4
Table (a_b)
id
a_id
b_id
date
1
1
1
2022-09-06
2
1
2
2022-09-06
3
1
1
2022-09-07
4
1
2
2022-09-07
5
1
1
2022-09-10
6
1
2
2022-09-10
If I want the latest records before 2022-09-09 the Output should be
id
a_name
b_name
date
1
aa
b1
2022-09-07
2
aa
b2
2022-09-07
This is can be done using pure SQL:
select a.id,a.name,b.name,a_b.date
from a
LEFT JOIN a_b on a_b.a_id = a.id
INNER JOIN b on b.id = a_b.b_id
where a.id = 1
AND a_b.date = (
select max(a_b.date) from a
LEFT JOIN a_b on a_b.a_id = a.id
INNER JOIN b on b.id = a_b.b_id
WHERE a.id = 1 AND a_b.date < = '2022-09-09')
How can I achieve the same output using Laravel eloquent using (with)?
A::with([
'B'=> function ($query) use ($date) {
/// what should I write here
}])->get()
here is an exact conversion from your sql to laravel
A::select('a.id', 'a.name', 'b.name', 'a_b.date')
->leftJoin('a_b', 'a_b.a_id', '=', 'a.id')
->join('b', 'b.id', '=', 'a_b.b_id')
->where('a.id', 1)
->where('a_b.date', function($query) {
$query->selectRaw('max(`a_b`.`date`)')
->from('a')
->leftJoin('a_b', 'a_b.a_id', '=', 'a.id')
->join('b', 'b.id', '=', 'a_b.b_id')
->where('a.id', 1)
->where('a_b.date', '<=', '2022-09-09');
})
->get()
I can't figure out how to use mysql max function with pivot tables. in laravel you can use ->withPivot() and ->wherePivot() on relationships, but im not sure how to limit to 1 (latest)
It seems it's only possible with an inner join using a sub query https://stackoverflow.com/a/12526264/10917416. using this method actually does a double join and is a bit messy (im sure it can probably be cleaned up)
A::with([
'b' => function ($query) {
$query->join(
DB::raw('('.
DB::table('a_b')
->selectRaw('`b_id`, max(`a_b`.`date`) as max_date')
->groupBy('b_id')
->where('a_b.date', '<=', DB::raw(':max_date'))
->toSql()
.') AB_2'), // end DB::raw
'b.id',
'=',
'AB_2.b_id')
->select('max_date as date', 'name', 'b.id')
->setBindings(['max_date'=>'2022-09-09']);
}
])->get();
That being said, i'm not sure whats wrong with your implementation using joins. I guess you'll need to test for performance

Any idea how to Convert this to Laravel Query Builder

DB::select("select encoded_datas.* from encoded_datas inner join
(select data_user_firstname, data_user_lastname, data_user_barangay from encoded_datas t
group by data_user_firstname, data_user_lastname, data_user_barangay
having count(*)>1) t1
on encoded_datas.data_user_firstname=t1.data_user_firstname and encoded_datas.data_user_lastname=t1.data_user_lastname and encoded_datas.data_user_barangay=t1.data_user_barangay");
It's a working piece of query code, but it is so slow to load compare to Eloquent/Proper Query Builder.
Can anyone here help me convert this to Laravel's Query Builder format..
try this solution
DB::connection(your_connection)
->table('encoded_datas')
->select('encoded_datas.*')
->join(
DB::raw("SELECT data_user_firstname, data_user_lastname, data_user_barangay FROM encoded_datas t GROUP BY data_user_firstname, data_user_lastname, data_user_barangay HAVING COUNT(*) > 1) t1"),
function($join {
$join->on('encoded_datas.data_user_firstname', '=', 't1.data_user_firstname')
->on('encoded_datas.data_user_lastname', '=', 't1.data_user_lastname')
->on('encoded_datas.data_user_barangay', '=', 't1.data_user_barangay');
})
)
but I don't think it will speed up execution
Sometimes sending multiple requests might be less expensive then sending one nested.
You can try getting the ids of the duplicate rows first
$ids = DB::table('datas')
->select('firstname','lastname', DB::raw('COUNT(*) as `count`'))
->groupBy('firstname', 'lastname')
->havingRaw('COUNT(*) > 1')
->pluck('id');
Then get datas
$datas = Datas::whereIn('id', $ids)->get();
In your example you are executing two queries and a join.
Here we are executing 2 queries only, 1 of which uses primary key index, which should be instant. Technically its should be faster, looks cleaner as well
I've tried Alexandr's code:
$ids = DB::table('datas')
->select('firstname','lastname', DB::raw('COUNT(*) as `count`'))
->groupBy('firstname', 'lastname')
->havingRaw('COUNT(*) > 1')
->pluck('id');
$datas = Datas::whereIn('id', $ids)->get();
But it only shows single data/record.. What i want to get is something like this:
**id** |firstname |lastname
1 | John | Legend
2 | john | Legend
3 | Michael | Mooray
4 | Smith | West
5 | smith | West
so Im expecting to get the following result:
john |Legend
john |Legend
Smith |West
Smith |West

Failed to get result using laravel query builder to join two table

I have two tables 'users' and 'channel'
Table: users
id name channel
1 user1 1,2,3
2 user2 2,3
3 user3 2
Table: channel
id channel_name
1 IT
2 CS
3 EC
I need result as
name channel_name
user1 IT,CS,EC
user2 CS,EC
user3 CS
Using laravel query builder how I write the query?
I tried below, but I got channel_name as NULL.
try 1
$UserChannelList = Users::select('users.name as username', DB::raw("(GROUP_CONCAT(channels.channel_name SEPARATOR ',')) as 'channel_name'"))
->leftjoin('channels', function ($join) {
$join->whereRaw("FIND_IN_SET('channels.id', 'users.channel')");
})
->groupBy('users.name')
->orderBy('users.name', 'ASC')
->get();
try 2
$UserChannelList = Users::select('users.name as username', DB::raw("(GROUP_CONCAT(channel.channel_name SEPARATOR ',')) as 'channel_name'"))
->leftjoin('channel', function ($join) {
$join->on(DB::raw("CONCAT(',', 'users.channel', ',')"), 'like', DB::raw("CONCAT(',','channel.id',',')"));
})
->groupBy('users.name')
->orderBy('users.name', 'ASC')
->get();
Try with this query.
\DB::table("users")
->select("users.*",\DB::raw("GROUP_CONCAT(channels.channel_name) as channel_name"))
->leftjoin("channels",\DB::raw("FIND_IN_SET(channels.id,users.channel)"),">",\DB::raw("'0'"))
->get();
Please check my answer
Here is your solution please check
$UserChannelList = DB::table('users')
->select('users.name', DB::raw("(GROUP_CONCAT(channels.channel_name)) as 'channel_name'"))
->rightJoin('channels', function($join){
$join->whereRaw('FIND_IN_SET(channels.id, users.channel)');
})
->groupBy('users.name')
->orderBy('users.name', 'ASC')
->get();

Laravel Eloquent select all rows with max created_at

I have a table that contains:
id seller_id amount created_at
1 10 100 2017-06-01 00:00:00
2 15 250 2017-06-01 00:00:00
....
154 10 10000 2017-12-24 00:00:00
255 15 25000 2017-12-24 00:00:00
I want to get all the latest rows for each individual seller_id. I can get the latest row for one like this:
$sales = Snapshot::where('seller_id', '=', 15)
->orderBy('created_at', 'DESC')
->first();
How do I get only the latest row for each seller?
To get latest record for each seller_id you can use following query
select s.*
from snapshot s
left join snapshot s1 on s.seller_id = s1.seller_id
and s.created_at < s1.created_at
where s1.seller_id is null
Using query builder you might rewrite it as
DB::table('snapshot as s')
->select('s.*')
->leftJoin('snapshot as s1', function ($join) {
$join->on('s.seller_id', '=', 's1.seller_id')
->whereRaw(DB::raw('s.created_at < s1.created_at'));
})
->whereNull('s1.seller_id')
->get();
This worked:
DB::table('snapshot as s')
->select('s.*')
->leftJoin('snapshot as s1', function ($join) {
$join->on('s.seller_id', '=', 's1.seller_id');
$join->on('s.created_at', '<', 's1.created_at');
})
->whereNull('s1.seller_id')
->get();

Laravel. Eloquent query for two tables

I want to write laravel eloquent query which could select all the titles from titles table where title_id doesnt't exist in title_count table. Here is an example. titles table:
title_id
1
2
3
4
title_count table:
title_id
3
4
So my query should select titles with id's 1, 2 from title table. To be honest, I have no ideo how to do it. I'm using laravel 5. I hope you can help me. Thanks in advance!
Use a join to to identify titles that do not appear in title_count.
DB::table('titles')->leftJoin('title_count', 'titles.title_id', '=', 'title_count.title_id')
->select('titles.*')
->whereNull('title_count.title_id')
->get();
Try this
DB::table('titles')->whereNotExists(function($query)
{
$query->select(DB::raw(1))
->from('title_count')
->whereRaw('title_count.title_id = titles.title_id');
})->get();
Not tested
DB::table('title_count')
->leftJoin('titles as t', 't.title_id', '=', 'title_count.title_id')
->select('t.*')
->where('t.title_id', '!=', 'title_count.title_id')
->get();

Categories