使用3個表(線程,標記,ThreadTag),我試圖選擇具有查詢中提供的所有標記的線程。在這個例子中,我需要有「聯邦快遞」和「運費」標籤的線程(S),所以預期的結果是2行:線程ID 1和4在多對多行中選擇與輸入完全匹配的行
線程表
+----------+----------------------------------+
| ThreadID | ThreadTitle |
+----------+----------------------------------+
| 1 | Can I choose Fedex for shipping? |
| 2 | Is Shipping Free |
| 3 | Can I use a credit card? |
| 4 | Does Fedex ship next day? |
| 5 | Is Fedex reliable? |
+----------+----------------------------------+
標籤表
+-------+-------------+
| TagID | TagName |
+-------+-------------+
| 1 | shipping |
| 2 | fedex |
| 3 | ups |
| 4 | price |
| 5 | free |
| 6 | credit card |
+-------+-------------+
ThreadTag表
+----------+-------+
| ThreadID | TagID |
+----------+-------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 5 |
| 3 | 6 |
| 4 | 1 |
| 4 | 2 |
| 5 | 2 |
+----------+-------+
這裏是我想出了代碼:
WITH ThreadsWithMatchingTags AS (
SELECT ThreadID
FROM ThreadTag tt
INNER JOIN Tag t on tt.TagID = t.TagID
WHERE TagName IN ('shipping', 'fedex')
GROUP BY ThreadID
HAVING COUNT(ThreadID) = 2
)
SELECT *
FROM Thread
WHERE ThreadID IN (SELECT ThreadID FROM ThreadsWithMatchingTags)
OUTPUT:
+----------+----------------------------------+
| ThreadID | ThreadTitle |
+----------+----------------------------------+
| 1 | Can I choose Fedex for shipping? |
| 4 | Does Fedex ship next day? |
+----------+----------------------------------+
其作品,但有一定有一個更好的辦法。
爲什麼?你的方法很好。 –
您可以使用內部連接而不是IN()和子查詢來代替CTE,但執行計劃可能非常相似 –
您需要在羣組中使用'GROUP BY ThreadID HAVING COUNT(ThreadID)= 2'嗎? – Amit