2015-08-21 94 views
0

我從下面的模式建立了一個簡單的線程即時通訊系統:檢索基於它的許多一對多的關係,現有的記錄

Schema

一個線程可以包含兩個或多個用戶,而且用戶可以屬於很多線程。當用戶嘗試創建新線程時,我需要檢查用戶之間是否存在現有線程(由ID指定),並返回現有線程。如果我指定的用戶是該線程中的只有個用戶,我應該只返回現有的線程。

通常情況下,我會使用這樣的查詢:

select distinct t.* from threads t 
inner join thread_users tu on tu.thread_id = t.id 
where tu.user_id in (1, 2); 

然而,這個查詢將返回線程,其中兩個用戶(ID 12)不在該線程只有用戶。我真正需要的是像only in (1, 2)條款。

我該如何達到與where only in條款相同的效果?

編輯:從一個相關的問題是出現在邊欄我張貼後,想出了這個:

select t.* from threads t 
inner join thread_users tu on tu.thread_id = t.id 
where tu.user_id in (1, 2) 
having count(distinct tu.user_id) = 2; 

似乎工作,但我可能會丟失,我有不具優勢的情況下佔我的數據庫數據?

+0

的可能重複[如何獲得一個ID與至少所有內容相關?](http://stackoverflow.com/questions/32137672/how-to-get-an-id-associated-with-at-least-all-contents) – Bulat

回答

2

這是set-in-a集子查詢的示例:您正在尋找線程內的用戶組。我喜歡用group byhaving解決這些問題,因爲這是一種非常靈活的方法。我認爲有以下你想要做什麼:

select t.* 
from threads t join 
    thread_users tu 
    on t.id = tu.thread_id 
group by t.id 
having sum(tu.user_id = 1) > 0 and 
     sum(tu.user_id = 2) > 0 and 
     sum(tu.user_id not in (1, 2)) = 0; 
+0

感謝您的回答戈登。我想我可能已經找到了一個解決方案,這個解決方案沒有什麼「有」陳述,我已經將它編輯到我的問題中。您的查詢是否存在某些邊緣案例,而我的查詢沒有? –

+1

@JohnDorean。 。 。它似乎沒有回報你想要的。如果用戶1,2和3在一個線程中,我的查詢將不會返回該線程。你的意志。 –

+0

啊,我混淆了我的測試數據。它確實返回了錯誤的線索。謝謝! :) –

0

此查詢將讓你跟帖說有兩個用戶12只有那些用戶的想法:

SELECT t.id 
FROM threads t join 
    thread_users tu 
    on t.id = tu.thread_id 
GROUP by t.id 
HAVING COUNT(distinct user_id) = 2 
    AND SUM (CASE WHEN user_id NOT IN (1, 2) THEN 1 ELSE 0 END) = 0 
+1

這實際上是返回我兩個線程在我的測試模式時,它應該只返回一個。我有兩個線程,第一個擁有用戶'1','2','3',第二個擁有用戶'1'和'2',這是我想要返回的線程。 –

+0

你是對的,應該有兩個條件排除(1,2,3)的情況。更新了答案。 – Bulat