Laravel Eloquent select all rows with max created_at - php

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

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

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

how to get highest 5 values from column?

I have products table with name and no_of_sell column..
I wanted to get highest 5 sold products based on no_of_sell column from products table.
how do i use it with query builder?
$propular_products = DB::table('users')
->join('products','products.auth_id','users.id')
->select('products.*')
->orderBy('products.no_of_sell', 'desc')
->where('products.status','=','1')
->paginate(5);
suppose products table:
name no_of_sell
x 6
y 9
z 10
t 23
u 3
h 11
r 5
i wanted to find
products list of 5 max no_of_sell ie, x y z t h
So if I understand it correctly in the column no_of_sell is a int. I should write it as follow :
$best_sell = DB::table('products')
->orderBy('no_of_sell', 'desc')
->limit(5)
->where('products.status','=','1')
->paginate(4)
->get();
https://laravel.com/docs/5.4/queries#retrieving-results
https://laravel.com/docs/5.4/queries#ordering-grouping-limit-and-offset
$best_sell = DB::table('products')
->select('no_of_sell')
->where('products.status','=','1')
->orderBy('no_of_sell', 'desc')
->paginate(4);
$best_sell = DB::table('products')
->select() // your selection criteria
->where('products.status','=','1')
->take(5)->get();

How to extract all rows which is duplicates in laravel?

I want to get all rows which is the same name and location from Users Table
**id** |name |location |phone_number
1 |John | Europe |0988884434
2 |john | Europe |0933333333
3 |Michael |Europe |0888888888
4 |Smith |Dubai |082388888888
5 |Smith |Dubai | 03939494944
I want to get all rows which is the same name and location like
john |Europe
john |Europe
Smith |Dubai
Smith |Dubai
here is how i tried to do
$duplicates = DB::table('users')
->select('name','location', DB::raw('COUNT(*) as `count`'))
->groupBy('name', 'location')
->having('count', '>', 1)
->get();
but this is just showing only one row which is duplicates like
john |Europe
Smith|Dubai
Any help or advice you have would be greatly appreciated.
Use havingRaw:
$duplicates = DB::table('users')
->select('name','location', DB::raw('COUNT(*) as `count`'))
->groupBy('name', 'location')
->havingRaw('COUNT(*) > 1')
->get();
I also wasn't sure of the syntax, but the Laravel documentation seems to imply that the alias you defined in the select clause is not available in the normal having() function.
To get All Rows rather than a total count of a group of duplicate rows would look like the following;
$duplicates = DB::table('users')
->select('id', 'name', 'location')
->whereIn('id', function ($q){
$q->select('id')
->from('users')
->groupBy('name', 'location')
->havingRaw('COUNT(*) > 1');
})->get();

Laravel Eloquent ORM query

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

Categories