Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL - One record per date

Right now im having the following data:

        Name          Time

       picture  2012-07-23 17:00:00
       picture  2012-07-24 18:00:00
       picture  2012-07-24 19:00:00
       picture  2012-08-03 08:40:06
       picture  2012-08-03 08:42:39
       picture  2012-08-03 08:54:03
       picture  2012-08-03 10:38:58
       picture  2012-08-03 10:39:55
       picture  2012-08-06 08:12:14

And the following SQL query:

    SELECT DATE_FORMAT(DATE(DATE_SUB(time,INTERVAL 4 HOUR)),GET_FORMAT(DATE,'ISO'))
    as time, uri, media_id, description
    FROM media WHERE place_id = 1 
    GROUP BY time ORDER BY time DESC 

Which works well and gives me the data i want. But the data from each unique date is ordered by the oldest date from each "day". I want it ordered by the newest. The Order By statement just order the whole result, not the dates for each day. If o just could take the newest date instead of the oldest when using Group By, but guess i have to work out something else than group by.

Edit: The following works. But i i want to return more columns from the subquery, how do I do that?

    SELECT Distinct DATE_FORMAT( DATE( DATE_SUB(time, INTERVAL 4 HOUR ) ) ,
    GET_FORMAT( DATE,  'ISO' ) ) AS date, 
            (SELECT type FROM media WHERE 
            DATE_FORMAT( DATE( DATE_SUB(time, INTERVAL 4 HOUR ) ) ,
           GET_FORMAT( DATE,'ISO' ) )  = date Order by time DESC Limit 1) as name
    FROM media
like image 823
joxxe Avatar asked Jan 15 '23 21:01

joxxe


1 Answers

Use a subquery to return the maximum Time for each day:

SELECT  MAX(Time) AS Time
FROM    Media
WHERE   Place_ID = 1
GROUP BY CAST(Time AS DATE)

Then join this back to your media table to limit the results to one for each day:

SELECT  Type AS Name,
        DATE_FORMAT(DATE(DATE_SUB(Media.time, INTERVAL 4 HOUR)), GET_FORMAT(DATE, 'ISO')) AS Time,
        uri, 
        media_id, 
        description
FROM    Media
        INNER JOIN
        (   SELECT  MAX(Time) AS Time
            FROM    Media
            WHERE   Place_ID = 1
            GROUP BY CAST(Time AS DATE)
        ) MaxTime
            ON MaxTime.Time = Media.Time;

A massive benefit of this solution is that the principal applies accross all DBMS, whereas currently MySQL is the only one I am aware of that supports columns in the select statement that are not part of an aggregate function or contained in the group by statement. I have recently written another answer on SO describing the potential hazards of this functionality in MySQL, and why it is not supported in other DMBS yet.

Example on SQLFiddle

like image 53
GarethD Avatar answered Jan 24 '23 18:01

GarethD