katie hudson
katie hudson

Reputation: 2893

Distinct most recent data from database

I am storing data in my database. The data being stored looks like this

id  | upload_month | created_at
-----------------------------------------
1   | January      | 2017-01-30 13:22:39
-----------------------------------------
2   | Febuary      | 2017-01-30 13:23:42
-----------------------------------------
3   | January      | 2017-01-30 13:25:33

Within my Controller I am trying to retrieve the distinct upload_month, but get the latest inserted version for each. At the moment I am trying

$uploadedFile = UploadedFile::groupBy('upload_month')->orderBy('created_at', 'desc')->get();

The problem is that this is returning the following

id  | upload_month | created_at
-----------------------------------------
1   | January      | 2017-01-30 13:22:39
-----------------------------------------
2   | Febuary      | 2017-01-30 13:23:42
-----------------------------------------

So for the January record it is giving the older version. If I change it to ->orderBy('created_at', 'asc') it returns the same records but Febuary being the first row.

In essense, what I am after is this

id  | upload_month | created_at
-----------------------------------------
1   | January      | 2017-01-30 13:25:33
-----------------------------------------
2   | Febuary      | 2017-01-30 13:23:42
-----------------------------------------

How am I able to achieve this?

Thanks

Upvotes: 4

Views: 3540

Answers (3)

CZ Tang Choo Zin
CZ Tang Choo Zin

Reputation: 9

I faced this issue and solved it this way.

UploadedFile::select(DB::raw('upload_month, MAX(created_at) as latest_date'))
->groupBy('upload_month')->orderBy('latest_date', 'desc')->get()

Upvotes: 0

Haider Ali
Haider Ali

Reputation: 1121

You should use the latest() method instead of orderBy:

UploadedFile::latest()->distinct()->get();

Upvotes: 0

Felippe Duarte
Felippe Duarte

Reputation: 15131

You should GROUP BY all fields you want to select, no only one. This article explain the issue: https://www.psce.com/blog/2012/05/15/mysql-mistakes-do-you-use-group-by-correctly/

The proper SQL query in this case would be:

SELECT id, upload_month, created_at
  FROM uplodaded_file
  JOIN (SELECT upload_month, MAX(created_at) created_at
          FROM uplodaded_file
      GROUP BY upload_month) months
    ON upload_month = months.upload_month
   AND created_at = months.created_at

The eloquent version of this is a little bit tricky. It will be better to use a raw query in this case.

Upvotes: 4

Related Questions