2009-11-09 32 views
2

我有這樣的一個MySQL數據庫:摔跤與SQL

table Message 
    sender_id int 
    recipient_id int 
    created datetime 
    [title, body, etc... omitted] 

是否有可能從該得到的,在一個查詢中,誰一直與ID給定用戶通信的所有用戶的列表N(表示N出現在sender_idrecipient_id),按created排序,包括最近值created,沒有重複項(無發送者/接收者對N,M和M,N)?

我很肯定答案是否定的,但我無法說服自己。下午精神呆滯。

如果否,那麼您會推薦什麼樣的最有效的替代方案?


編輯:聖潔的廢話,堆棧溢出這些天跳。在我意識到8個答案之前,我忘記了指定我想在每行中存在最近值created以及其他用戶ID。

+0

一切聽起來很簡單,除了「無發件人/接受者雙'重複部分 – 2009-11-09 20:47:02

+0

'M'代表你的要求是什麼?你是說你不想要自我引用? – 2009-11-09 20:50:39

+0

M是另一個用戶的ID。我最終想要的是M列表及其相關的最近創建時間。 – lawrence 2009-11-09 20:56:25

回答

3

用途:

SELECT x.friend, 
     MAX(x.created) 
    FROM (SELECT t.recipient_id 'friend', 
       t.created 
      FROM MESSAGE t 
     WHERE t.sender_id = @id 
     UNION 
     SELECT r.sender_id 'friend', 
       r.created 
      FROM MESSAGE r 
     WHERE r.recipient_id = @id) x 
GROUP BY x.friend 
+0

我剛剛完成從原始發佈寫了我自己的版本,但我刪除它,因爲你應該得到信用 – lawrence 2009-11-09 21:13:02

1

不,這很容易做到。

SELECT DISTINCT IF(sender_id=4, recipient_id, sender_id) AS partner_id 
FROM message 
WHERE sender_id=4 OR recipient_id=4 
+0

這樣你就不需要一個UNION。 顯然你必須用你的用戶ID替換4。 – Franz 2009-11-09 20:54:33

+0

啊,這很接近。不幸的是,我不清楚,我還需要時間戳本身,這意味着明顯突破,我想? – lawrence 2009-11-09 20:55:07

+0

爲什麼會打破DISTINCT? – Franz 2009-11-09 20:55:44

0

很明顯,你無法說服自己,否則你不會問。我很肯定答案是肯定的。然而,在不瞭解底層數據的某些特點的情況下,找到正確的解決方案有點困難。

它可能進入的

select 
    sender_id, 
    recipient_id 
from 
    message 
where 
(sender_id = n or 
    recipient_id = n ) 
order by 
    created desc 
4

方向試試這個

SELECT distinct recipient_id 
FROM Message 
WHERE sender_id = @id 

UNION 

SELECT distinct sender_id 
FROM Message 
WHERE recipient_id = @id 

UNION子句將消除跨兩個查詢重複。實際上看着它,你不會需要獨特的,因爲工會也會爲你這樣做(任何人的任何想法,如果使用不同的預先過濾條款或讓工會處理所有的重複更有效)?

+1

需要'創建ORDER BY' – 2009-11-09 20:53:40

+0

我自己我只是做一個視圖,然後用它來回到表中的任何其他領域 – Cruachan 2009-11-09 21:00:06

+0

我猜UNION可能更快,因爲DISTINCT很慢。此外,只有在使用DISTINCT的情況下仍然允許重複,當與另一個人的通信通過發送和接收發生時... – Franz 2009-11-09 21:00:49

0

我認爲這將滿足您的要求最:

SELECT * 
FROM user 
WHERE 
    user_id in 
    (select recipient_id FROM message m where m.sender_id = X) 
    OR user_id in 
    (select sender_id FROM message m where m.recipient_id = X) 
order by 
    created DESC 

有沒有重複,沒有工會,沒有SQL方言具體的東西。

1

這裏是我:)

select id, max(created) as lastMessage 
(
    select sender_id as id, created 
    from Message 
    union 
    select recipient_id as id, created 
    from Message 
) as MergedMessage 
where id = ?id 
group by id 
order by max(created) desc 

就是這樣:

  • 沒有重複
  • 爲了通過創建降序