我在SQLite 3中有一个如下所示的模式:
CREATE TABLE tags(id INTEGER PRIMARY KEY, tag TEXT NOT NULL, UNIQUE(tag));
CREATE TABLE files(id INTEGER PRIMARY KEY, name TEXT NOT NULL, UNIQUE(name));
CREATE TABLE filetags(file_id INT NOT NULL, tag_id INT NOT NULL, UNIQUE(file_id, tag_id), FOREIGN KEY(file_id) REFERENCES files(id), FOREIGN KEY(tag_id) REFERENCES tags(id));
我一直在尝试编写一个查询,对于给定的文件ID,它会显示每个标记以及是否为该ID设置了该标记。我能得到的最接近的是:
SELECT * FROM tags t
LEFT OUTER JOIN filetags ft ON ft.tag_id=t.id
LEFT OUTER JOIN files f ON f.id=ft.file_id WHERE f.id=@0 OR
f.id IS NULL
这适用于具有1个或多个标记的文件,但对于没有标记的文件,它会排除所有至少包含一个文件的标记。我已经尝试了几种变体,但似乎受限于必须解决sqlite缺乏完整和正确的连接。
答案 0 :(得分:1)
从概念开始:“我想要所有文件和所有标签”:
SELECT * FROM files f CROSS JOIN tags t
现在您需要附加“该文件是否确实设置了该标记”:
SELECT * FROM files f CROSS JOIN tags t
LEFT JOIN filetags ft ON ft.file_id=f.id AND ft.tag_id=t.id
为了一点点的润色,它的化妆品别名:
SELECT f.*, t.*, (ft.file_id IS NOT NULL) AS file_has_tag
FROM files f CROSS JOIN tags t
LEFT JOIN filetags ft ON ft.file_id=f.id AND ft.tag_id=t.id