Search code examples
mysqlsqlsql-date-functionssqldatetime

Grouping DATETIME by DATE in MySQL and showing the last record of the day


I have a group of currency quotations that change every hour or so. For the sql results in this particular example, I only need the last available record of each day of the last 30 days in yyyy-mm-dd format.

This is my current query:

SELECT value, DATE(date_quotation) as date_q
FROM quotation
GROUP BY DATE(date_quotation)
ORDER BY date_q DESC LIMIT 30

This is used for a histogram chart, where the x axis shows separated days. The quotations table has these columns:

  • id_quotation (INT)
  • date_quotation (DATETIME)
  • value (DECIMAL)

The problem is that it doesn't necessarily bring the last record of the day. It is grouping the records by day, but it should display the one with the highest hour/minute/second. Any ideas? Thanks!


Solution

  • You can leverage non-standard behavior of MySQL GROUP BY extension and do

    SELECT DATE(date_quotation) date_q, value
      FROM
    (
      SELECT value, date_quotation
        FROM quotation
       WHERE date_quotation >= CURDATE() - INTERVAL 30 DAY
         AND date_quotation <  CURDATE() + INTERVAL 1 DAY
       ORDER BY date_quotation DESC
    ) q
      GROUP BY DATE(date_quotation)
    

    or you can do it by the book by selecting a max value of date_quotation per day (assuming that there is no duplicates) and then join back to quotation to pick up value

    SELECT date_q, value
      FROM
    (
      SELECT DATE(date_quotation) date_q, MAX(date_quotation) date_quotation
        FROM quotation
       WHERE date_quotation >= CURDATE() - INTERVAL 30 DAY
         AND date_quotation <  CURDATE() + INTERVAL 1 DAY
       GROUP BY DATE(date_quotation)
    ) t JOIN quotation q 
        ON t.date_quotation = q.date_quotation
    

    Note: that both queries use an index-friendly way to filter for date period. Make sure that you have an index on date_quotation column.

    Here is SQLFiddle demo