0

我希望这个问题的答案与 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     ║
 ╚═════════╩═══════════╝

感谢这篇博文让我变得懒惰)

这实质上是说:

  1. 苹果是(红色,有光泽,美味,美味)
  2. 橙子是(橙子)
  3. 葡萄柚是(橙色,可怕)

现在说我想选择那些带有“橙色”标签的水果,而没有其他水果。有了所提供的数据,那将只是具有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

这将在结果中返回橙色和葡萄柚,但我只想要橙色。

我以这种方式执行 SQL 语句的原因是不同类型的水果可能具有相同的名称但不同的标签,或者不同的水果可能只有一个相同的标签。

编辑:

SQLFiddle 按要求

4

1 回答 1

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(). 此外,Access 通常需要在连接周围使用很多难看的括号,我也将其省略。

于 2015-03-03T21:01:11.053 回答