我有三个 SQLite 表,使用以下脚本创建
PRAGMA foreign_keys = ON;
CREATE TABLE IF NOT EXISTS entries(
timestamp TEXT,
title TEXT,
body TEXT
);
CREATE TABLE IF NOT EXISTS tags(
tag TEXT
);
CREATE TABLE IF NOT EXISTS entry_tags(
entry_id INTEGER;
tag_id INTEGER,
FOREIGN KEY (entry_id) REFERENCES entries(rowid),
FOREIGN KEY (tag_id) REFERENCES tags(rowid)
);
我的问题很简单,但我不知道如何回答。如何使用 SQL 获取条目的时间戳、标题、正文和所有关联标签?我假设它涉及到过程中某个地方的 JOIN,但尽管进行了搜索,我找不到我能理解的答案。
是的,您想使用您的
entry_tags
连接表进行 JOIN。像这样的东西(注意我只是使用 Sqlite 命令行工具,而不是 Python 模块,但 SQL 命令是相同的):
sqlite> select e.timestamp, e.title, e.body, t.tag
...> from entries as e
...> join entry_tags et on e.rowid = et.entry_id
...> join tags as t on et.tag_id = t.rowid;
┌────────────┬───────────┬────────────────┬───────┐
│ timestamp │ title │ body │ tag │
├────────────┼───────────┼────────────────┼───────┤
│ 2024-11-01 │ Article A │ blah blah blah │ alpha │
│ 2024-11-01 │ Article A │ blah blah blah │ beta │
└────────────┴───────────┴────────────────┴───────┘
但是,请注意,如果一篇文章上有多个标签,您将获得重复的行。在这种情况下,您可以使用
group_concat
函数(参见sqlite中的字符串聚合)来聚合标签(默认以逗号分隔):
sqlite> select e.timestamp, e.title, e.body, group_concat(t.tag) as tags
...> from entries as e
...> join entry_tags et on e.rowid = et.entry_id
...> join tags as t on et.tag_id = t.rowid;
┌────────────┬───────────┬────────────────┬────────────┐
│ timestamp │ title │ body │ tags │
├────────────┼───────────┼────────────────┼────────────┤
│ 2024-11-01 │ Article A │ blah blah blah │ alpha,beta │
└────────────┴───────────┴────────────────┴────────────┘
顺便说一句,请注意,Sqlite 通常不会让您使用隐式
rowid
列作为主键并引用作为外键,除非您显式地将其放入表架构中(请参阅 https://www.sqlite .org/rowidtable.html)。例如,您应该如下定义 entries
和 tags
:
CREATE TABLE entries(
rowid INTEGER PRIMARY KEY,
timestamp TEXT,
title TEXT,
body TEXT
);
CREATE TABLE tags(
rowid INTEGER PRIMARY KEY,
tag TEXT
);