2014-11-07 69 views
1

我有兩個SQL表usersmessages它看起來像這樣:獲取最新的結果與GROUP BY基於JOIN

user_id | username 
--------|--------- 
     1 | alice 
     2 | bob 
     3 | carol 

message_id | sending_user_id | message | created_utc 
-----------|-----------------|---------|------------- 
      1|    1 | a  | 67 
      2|    1 | b  | 68 
      3|    3 | c  | 69 
      4|    2 | d  | 70 
      5|    3 | e  | 71 
      6|    1 | f  | 72 

我試圖寫一個SQL查詢,將導致最新messageusercreated_utc排列的message取消。所以結果應該是這樣的:

message_id | sending_user_id | message | created_utc | sending_username 
-----------|-----------------|---------|-------------|---------------------- 
      6|    1 | f  | 72   | alice 
      5|    3 | e  | 71   | carol 
      4|    2 | d  | 70   | bob 

我卡在如何保證信息總是最新的用下面的查詢:

SELECT messages.message_id, messages.sending_user_id, messages.message, messages.created_utc, users.username AS sending_username 
FROM messages 
LEFT JOIN ON users 
WHERE messages.sending_user_id=users.user_id 
GROUP BY messages.sending_user_id 
ORDER BY messages.created_utc DESC 

編輯:我使用PostgreSQL 9.3.5

+0

請標記與你的問題你正在使用的數據庫。 – 2014-11-07 01:11:47

+0

@GordonLinoff done – 2014-11-07 01:14:54

+1

許多相同的問題。 http://stackoverflow.com/questions/3800551/select-first-row-in-each-group-by-group/7630564 – 2014-11-07 02:55:27

回答

3

隨着Postgres的,我會建議distinct on

SELECT DISTINCT ON (m.sending_user_id) m.message_id, m.sending_user_id, m.message, m.created_utc, 
     u.username AS sending_username 
FROM messages m LEFT JOIN 
    users u 
    on m.sending_user_id = u.user_id 
ORDER BY m.sending_user_id, m.created_utc DESC; 

如果你想最終order by,使用子查詢:

SELECT um.* 
FROM (SELECT DISTINCT ON (m.sending_user_id) m.message_id, m.sending_user_id, m.message, m.created_utc, 
       u.username AS sending_username 
     FROM messages m LEFT JOIN 
      users u 
      on m.sending_user_id = u.user_id 
     ORDER BY m.sending_user_id, m.created_utc DESC 
    ) um 
ORDER BY created_utc; 
+0

這保證了最新的消息,但不按照'created_utc'列排序表。編輯完成後 – 2014-11-07 01:33:14

+0

完美! – 2014-11-07 01:39:32

0

我認爲最好的(也是最靈活)ANSI SQL解決方案是一個與NOT EXISTS

SELECT m1.message_id, m1.sending_user_id, m1.message, m1.created_utc, users.username AS sending_username 
FROM  messages m1 
LEFT JOIN users ON (m1.sending_user_id=users.user_id) 
WHERE  NOT EXISTS (
      SELECT * 
      FROM messages m2 
      WHERE m2.sending_user_id = m1.sending_user_id 
      AND m2.created_utc < m1.created_utc 
     )