简体   繁体   中英

how to select all newest records for all users

i have a appointment table where i need to select the newest record for all users, currently my query is returning the oldest for each userid instead of the newest one for each

Appointment table

+-------+--------------+--------------+--------------+
| ID    | time         | userid       | description  |
+-------+--------------+--------------+--------------+
| 1     | 2017-10-20   | 4            | etc          |
+-------+--------------+--------------+--------------+
| 2     | 2017-10-21   | 6            | etc          |
+-------+--------------+--------------+--------------+
| 3     | 2017-10-22   | 7            | etc          |
+-------+--------------+--------------+--------------+
| 4     | 2017-10-23   | 8            | etc          |
+-------+--------------+--------------+--------------+
| 5     | 2017-10-24   | 6            | etc          |
+-------+--------------+--------------+--------------+
| 6     | 2017-10-25   | 7            | etc          |
+-------+--------------+--------------+--------------+

users table

+-------+--------------+--------------+--------------+
| ID    | first        | last         | status       |
+-------+--------------+--------------+--------------+
| 4     | jo           | do           | 1            |
+-------+--------------+--------------+--------------+
| 6     | jid          | did          | 1            |
+-------+--------------+--------------+--------------+
| 7     | jone         | done         | 1            |
+-------+--------------+--------------+--------------+
| 8     | ja           | da           | 1            |
+-------+--------------+--------------+--------------+

CURRENT QUERY

$sql = "SELECT *
        FROM appointment 
        LEFT JOIN users AS user
        ON user.id = appointment.userid
        WHERE user.status = 1
        GROUP BY appointment.userid
        ";

CURRENT RESULT

+-------+--------------+--------------+--------------+
| ID    | time         | userid       | description  |
+-------+--------------+--------------+--------------+
| 1     | 2017-10-20   | 4            | etc          |
+-------+--------------+--------------+--------------+
| 2     | 2017-10-21   | 6            | etc          |
+-------+--------------+--------------+--------------+
| 3     | 2017-10-22   | 7            | etc          |
+-------+--------------+--------------+--------------+
| 4     | 2017-10-23   | 8            | etc          |
+-------+--------------+--------------+--------------+

EXPECTED OUTPUT

+-------+--------------+--------------+--------------+
| ID    | time         | userid       | description  |
+-------+--------------+--------------+--------------+
| 1     | 2017-10-20   | 4            | etc          |
+-------+--------------+--------------+--------------+
| 4     | 2017-10-23   | 8            | etc          |
+-------+--------------+--------------+--------------+
| 5     | 2017-10-24   | 6            | etc          |
+-------+--------------+--------------+--------------+
| 6     | 2017-10-25   | 7            | etc          |
+-------+--------------+--------------+--------------+

Try this

SELECT a.ID, a.time, a.userid, a.description 
FROM users u
INNER JOIN appointment a ON u.id = a.userid
WHERE u.status = 1
AND time in(SELECT MAX(time) from appointment t WHERE t.userid = a.userid )

You can make a self join to identify the latest appointment:

SELECT s.* FROM (
    SELECT *
    FROM appointment 
    LEFT JOIN users AS user
     ON user.id = appointment.userid and user.status = 1) s
LEFT JOIN appointment p
 ON(p.userid = s.userid and p.time < s.time)
WHERE p.time IS NULL

Though I don't understand why the LEFT JOIN to users table.

SELECT MAX(a.ID) ID, MAX(a.time) time, a.userid, MAX(a.description) description
FROM appointment a
INNER JOIN users u ON u.id = a.userid
WHERE u.status = 1
GROUP BY a.userid
ORDER BY a.ID

Output

ID time                 userid description
1  2017-10-20T00:00:00Z 4      etc
5  2017-10-24T00:00:00Z 6      etc
6  2017-10-25T00:00:00Z 7      etc
4  2017-10-23T00:00:00Z 8      etc

SQL Fiddle: http://sqlfiddle.com/#!9/6b0c1c/7/0

I think the left join with user table is unnecessary . The following query will give the expected result

select a1.* from appointment a1
inner join (select max(id) as id ,userid from appointment group by userid) a2
on a1.id=a2.id

SQL Fiddle

SELECT max(appointment.id), max(time), user.id, description
FROM appointment 
LEFT JOIN users AS user
ON user.id = appointment.userid
WHERE user.status = 1
GROUP BY appointment.userid

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