【发布时间】:2019-01-22 11:24:07
【问题描述】:
在 SQLite 中,我有一个名为 Items 的表:
| id | name |
|----|-------|
| 1 | .. |
| 2 | .. |
| 3 | .. |
| 4 | .. |
| 5 | .. |
| 6 | .. |
每个项目都可能有与之关联的标签。标签存储在另一个表中,并有自己的 ID。项目和标签的关联存储在名为 Associations 的第三个表中:
| itemID | tagID |
|--------|--------|
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 3 | 4 |
| 3 | 5 |
| 4 | 5 |
如您所见,项目 1 有 3 个标签,项目 2 和 4 各有 1 个标签,项目 3 有 2 个标签。项目 5 和 6 没有标签,因此它们的 ID 不会出现在 Associations 表中。
现在,我想检索标签少于 2 个的项目的 ID,包括零标签。如果只是关于 Associations 表,任务很简单:
SELECT itemID FROM Associations GROUP BY itemID HAVING COUNT(tagID) < 3;
但这不会返回没有标签的项目的 ID,因为它们在 Associations 表中不存在。所以我想我必须以某种方式使用 JOIN 。我试过了
SELECT id FROM Items INNER JOIN Associations ON Associations.itemID=Items.id GROUP BY itemID HAVING COUNT(Associations.tagID) < 3;
但这似乎和前面的查询一样。 感谢您的帮助:)
编辑:所以,答案就是将INNER JOIN 替换为LEFT JOIN,将GROUP BY itemID 替换为GROUP BY Items.id。
问题扩展: 现在,要告诉秘密,标签(除了具有 ID)分为不同的类别,例如红色、绿色和蓝色(例如,ID 为 5 的红色标签和 id 为 5 的绿色标签实际上是不同的标签)。
| itemID | tagID |tagType|
|--------|--------|-------|
| 1 | 1 | red |
| 1 | 2 | red |
| 1 | 3 | blue |
| 2 | 1 | green |
| 3 | 4 | blue |
| 3 | 5 | red |
| 4 | 5 | blue |
所以我需要检索具有少于 N 个特定类型标签 的项目的 ID。我想我可以通过添加 WHERE 这样的子句来使用 Yogesh 的答案来轻松解决这个问题:
SELECT i.id AS itemID
FROM Items i LEFT JOIN
Associations a
ON a.itemID = i.id
WHERE a.tagType='red'
GROUP BY i.id
HAVING COUNT(a.tagID) < 3;
但这又一次无法返回根本没有标签的项目,因为它们现在被WHERE 条件过滤掉了。我想我需要这些方面的东西:
SELECT i.id AS itemID
FROM Items i LEFT JOIN
Associations a
ON a.itemID = i.id
GROUP BY i.id
HAVING COUNT(a.tagID WHERE a.tagType='red') < 3;
但这似乎不是一个有效的说法。再次感谢您的帮助;我可能会“重新接受”这个答案。
【问题讨论】:
-
使用
left join和group by items.id代替associations.itemid...