简体   繁体   中英

Get values of first record and last record by date in mysql subquery

I know that for some MySQL pro, this is reasonably straightforward. I further realize that the answer could likely be figured out from other answers , however I've spent some real time trying to build this query, and I can't seem to figure out how to apply those solutions to my situation.

Mine seems different than others who want the "min and max" of a field - but I need the value from another field based on the "min and max" of the date field.

Given the following structure - a "user" table, and an "entries" table:

Data Sample (for "entries" table):

id | user_id |     date     | value  
---+---------+--------------+-------
 1         1     2018-02-01     125
 2         5     2018-01-15     220
 3         1     2017-12-31     131
 4         4     2018-01-01      77
 3         1     2017-12-15     133

I'd like to know value of the first entry (by date) , the value of the last entry (by date), and the user_id.

The results should be:

user_id | first_date | first_value |  last_date | last_value
--------+------------+-------------+------------+-----------
      1   2017-12-15           133   2018-02-01          125
      4   2018-01-01            77   2018-01-01          133
      5   2018-01-15           220   2018-01-15          220

While I want the best solution, what I've been working on revolves around combining some queries like so:

SELECT user_id, l.date AS last_date, l.value AS last_value, f.date AS first_date, f.value AS first_value  
    FROM user AS u
    LEFT JOIN (SELECT user_id, date, value FROM entries ORDER BY date ASC LIMIT 1) AS f ON f.user_id = u.user_id
    LEFT JOIN (SELECT user_id, date, value FROM entries ORDER BY date DESC LIMIT 1) AS l ON l.user_id = u.user_id

NOTE: This doesn't work. If I wanted the "first entry" for someone, I would write a query that was SELECT user_id, date, value FROM entries ORDER BY date ASC LIMIT 1 - however, using it in the subqueries doesn't have the desired effect.

I've also tried some GROUP BY queries, with no success as well.

SQL Fiddle: http://sqlfiddle.com/#!9/71599

The following query gives you the expected result, but it's done without using a LEFT JOIN . So the NULL values are excluded.

SELECT 
    u.id AS user_id,
    e1.date AS first_date,
    e1.value AS first_value,
    e2.date AS last_date,
    e2.value AS last_value
FROM 
    users u, 
    (SELECT * FROM entries e ORDER BY date ASC) e1,
    (SELECT * FROM entries e ORDER BY date DESC) e2
WHERE
    e1.user_id = u.id
AND 
    e2.user_id = u.id
GROUP BY 
    u.id

And here's a working fiddle - http://sqlfiddle.com/#!9/71599/8

Also, it's worth noting that the LIMIT in your attempt would limit the results to 1 for all joined results, not each joined result. Either way, the LEFT JOIN didn't work. If anyone knows why, I'd be interested to understand.

Edit: Here's another attempt, this time utilising MIN() and MAX() , rather than ORDER BY . Unfortunately, you need to join the entries table multiple times for this to work though.

SELECT 
    u.id AS user_id,
    e1.date AS first_date,
    e1.value AS first_value,
    e2.date AS last_date,
    e2.value AS last_value
FROM users u
INNER JOIN entries e1 ON (u.id = e1.user_id)
INNER JOIN entries e2 ON (u.id = e2.user_id)
INNER JOIN (
    SELECT user_id, MIN(date) AS date
    FROM entries
    GROUP BY user_id
) e3 ON (e1.user_id = e3.user_id AND e1.date = e3.date)
INNER JOIN (
    SELECT user_id, MAX(date) AS date
    FROM entries
    GROUP BY user_id
) e4 ON (e2.user_id = e4.user_id AND e2.date = e4.date)
GROUP BY u.id

Another working fiddle: http://sqlfiddle.com/#!9/71599/18

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM