假设我有两个表record
和tag
,其中record
包含大量详细信息,tag
只包含记录与标签,即
表tag
包含以下列:
tag ENUM 'SomeTagA','SomeTagB','SomeTagC' NOT NULL
record_id INT NOT NULL
组合(tag
,record_id
)是唯一的。
现在,我可以使用(INNER)JOIN:
轻松查询正面关系SELECT r.*
FROM record AS r
JOIN tag AS t1 ON t1.record_id = r.id AND t1.tag = "SomeTagA"
JOIN tag AS t2 ON t2.record_id = r.id AND t2.tag = "SomeTagB"
然而,如果我想否定第三个标签怎么办?比如,选择所有包含标签A和标签B但不包含标签C的记录。我能想出的唯一解决方案是:
SELECT r.*
FROM record AS r
WHERE (SELECT COUNT(*) FROM tag WHERE tag = "SomeTagA" and record_id = r.id) = 1
AND (SELECT COUNT(*) FROM tag WHERE tag = "SomeTagB" and record_id = r.id) = 1
AND (SELECT COUNT(*) FROM tag WHERE tag = "SomeTagC" and record_id = r.id) = 0
但我可以想象这是一个有点慢的解决方案。
答案 0 :(得分:2)
您可以使用条件聚合来满足您的条件
SELECT r.col1, r.col2
FROM record AS r
JOIN tag AS t ON t.record_id = r.id
GROUP BY r.col1, r.col2
HAVING SUM(t.tag = 'SomeTagA') > 1
AND SUM(t.tag = 'SomeTagB') > 1
AND SUM(t.tag = 'SomeTagC') = 0
SUM(t.tag = 'SomeTagA')
可以表示为SUM(CASE WHEN t.tag = 'SomeTagA' THEN 1 ELSE 0 END)
,在mysql中使用sum和一些像sum(a = b)这样的表达式将得到一个布尔值,你将得到一个基于你的表达式的计数