我希望这个问题的答案是DBMS不可知的,但如果它是相关的,我使用的是Access SQL。
请注意,这是我想要做的简化版本。
现在,请考虑我有以下三个表。
我的主要水果表(tblFruits):
╔═════════╦═══════════╦
║ fruitID ║ fruitName ║
╠═════════╬═══════════╬
║ 1 ║ Apple ║
║ 2 ║ Orange ║
║ 3 ║ Grapefruit║
╚═════════╩═══════════╩
将许多标签链接到1个水果(tblFruitTagJunc)的联结表:
╔════════════════╦═════════╦═════════════╗
║ fruitTagJuncID ║ fruitID ║ tagID ║
╠════════════════╬═════════╬═════════════╣
║ 1 ║ 1 ║ 1 ║
║ 2 ║ 1 ║ 2 ║
║ 3 ║ 1 ║ 4 ║
║ 4 ║ 1 ║ 5 ║
║ 5 ║ 2 ║ 3 ║
║ 6 ║ 3 ║ 3 ║
║ 7 ║ 3 ║ 6 ║
╚════════════════╩═════════╩═════════════╝
最后是一个用于标记我的水果的标签表(tblTag):
╔═════════╦═══════════╗
║ tagID ║ tag ║
╠═════════╬═══════════╣
║ 1 ║ Tasty ║
║ 2 ║ Red ║
║ 3 ║ Orange ║
║ 4 ║ Shiny ║
║ 5 ║ Delicious ║
║ 6 ║ Awful ║
╚═════════╩═══════════╝
感谢This Blog Post让我变懒“
这基本上说明了:
现在说我要选择那些标有'Orange'而没有其他水果的水果。根据提供的数据,只有fruitName = 'Orange'
的数据。我目前正在这样做:
SELECT F.fruitName
FROM tblFruits F
INNER JOIN tblFruitTagJunc AS FTJ on F.fruitID = FTJ.fruitID
INNER JOIN tbltag as T ON FTJ.tagID = T.tagID
WHERE T.tag in('Orange')
GROUP BY F.fruitName
HAVING count(T.tag) = 1
结果会返回Orange和Grapfruit,但我只想要Orange。
我这样做SQL语句的原因是不同类型的水果可能具有相同的名称但不同的标签或不同的水果可能只有一个相同的标签。
编辑:
答案 0 :(得分:2)
您走在正确的轨道上,但您需要having
子句中的条件聚合,而不是where
子句。当您使用where
时,您永远不会看到其他标签。
所以:
SELECT F.fruitName
FROM tblFruits as F INNER JOIN
tblFruitTagJunc AS FTJ
on F.fruitID = FTJ.fruitID INNER JOIN
tbltag as T
ON FTJ.tagID = T.tagID
GROUP BY F.fruitName
HAVING SUM(iif(t.tag in ('Orange'), 1, 0) > 0 AND
COUNT(t.tag) = 1;
请注意"对"表达条件的方式是使用CASE
而不是IIF()
。访问通常需要在连接周围使用大量丑陋的括号,我也将其遗漏。