使用3个表(Thread,Tag,ThreadTag),我正在尝试选择包含查询中提供的所有标记的线程。在这个例子中,我需要有'fedex'和'shipping'标签的线程,所以预期的结果是2行:ThreadIDs 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)
输出:
+----------+----------------------------------+
| ThreadID | ThreadTitle |
+----------+----------------------------------+
| 1 | Can I choose Fedex for shipping? |
| 4 | Does Fedex ship next day? |
+----------+----------------------------------+
有效,但必须有更好的方法。
答案 0 :(得分:2)
以下是编写查询的另一种方式。
SELECT * from Thread th
WHERE(SELECT COUNT(*) from Tag ta, ThreadTag tt
WHERE ta.TagID = tt.TagID
AND tt.ThreadID = th.ThreadID
AND ta.TagName in ('fedex', 'shipping')) = 2;
答案 1 :(得分:1)
"更好的"是主观的,我总是比较优化器输出,因为你的解决方案没有任何问题。
话虽如此,我也会这样做: -
select
a.*
from
Thread a
where
(
select
count(*)
from
Tag b,
ThreadTag c
where
c.ThreadID = a.ThreadID and
b.TagID = c.TagID and
b.TagName in ('shipping', 'fedex')
) = 2;