如何选择所有相关字段并按这些字段过滤值

时间:2016-11-24 22:44:02

标签: sql sqlite

我有以下多对多关系:

CREATE TABLE IF NOT EXISTS bookmarks (
    id INTEGER PRIMARY KEY,
    title TEXT NOT NULL,
    url TEXT NOT NULL UNIQUE
)

CREATE TABLE IF NOT EXISTS tags (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL UNIQUE
)

CREATE TABLE IF NOT EXISTS bookmarks_tags (
    bookmark_id INTEGER NOT NULL,
    tag_id INTEGER NOT NULL,
    FOREIGN KEY(bookmark_id) REFERENCES bookmarks(id),
    FOREIGN KEY(tag_id) REFERENCES tags(id)
)

我想知道如何通过标签过滤书签,但仍然选择所有标签。

我有以下查询:

SELECT title, url, GROUP_CONCAT(tags.name)
FROM bookmarks
LEFT OUTER JOIN bookmarks_tags
    ON bookmarks.id = bookmarks_tags.bookmark_id
LEFT OUTER JOIN tags
    ON bookmarks_tags.tag_id = tags.id
WHERE tags.name = "tag1"
GROUP BY url

但如果书签包含多个标记,则只会返回tag1

AND tags.name = "tag2"子句中添加WHERE将不会返回任何结果。

那么如何在按标签过滤书签时选择所有标签?

1 个答案:

答案 0 :(得分:1)

您正在寻找带有至少一个tag1记录的书签。您可以在having子句中聚合后检查此内容。

SELECT b.title, b.url, GROUP_CONCAT(t.name)
FROM bookmarks b
JOIN bookmarks_tags bt ON b.id = bt.bookmark_id
JOIN tags t ON bt.tag_id = t.id
GROUP BY b.url
HAVING COUNT(CASE WHEN t.name = 'tag1' THEN 1 END) > 0;

外连接在这里没有任何意义,因为你只对有标签的书签感兴趣。