【发布时间】:2015-03-03 20:49:24
【问题描述】:
我希望这个问题的答案与 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让我偷懒)
这基本上是说:
- 苹果是(红色、有光泽、美味、美味)
- 橙子是(橙子)
- 葡萄柚是(橙色,可怕)
现在说我想选择那些带有“橙色”标签的水果,而没有其他水果。有了提供的数据,那将是只有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 语句的原因是不同类型的水果可能具有相同的名称但不同的标签,或者不同的水果可能只有一个相同的标签。
编辑:
【问题讨论】:
-
请注意,
tblFruitTagJunc.fruitTagJuncID列对您没有任何好处。你最好放弃它(以及它的相关索引,假设它是一个 PK)。既然您无论如何都需要 (fruitId, tagId) 上的唯一索引,只需将其设为 PK。 -
所以当你说你只想选择 Oranges 时,是指
fruitName = 'Orange'还是fruitID = 2? -
HAVING count(T.tag) = 1给你的水果只有一个标签。因此不需要where t.tag in ('Orange')。您的查询失败,因为您仅限于那些橙色的标签..已经排除了糟糕的标签(葡萄柚很好吃) -
@JohnBollinger 我已经读过很多次了,拥有独立的 PK 并且不需要它比没有它并且以后需要它要好。由于我遇到的大多数连接表都没有那么大,所以我总是尝试包含它。虽然我确实看到了这两种方式的利弊。
-
@Elias,最好不要也不需要。
标签: sql ms-access select junction-table