假设我有一个包含4个表的数据库,用于编目书籍。对于我想要存储标题的每本书,一个或多个作者以及一个或多个翻译者。 结构如下:
CREATE TABLE `book` (
`book_id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
`title` TEXT
);
CREATE TABLE `person` (
`person_id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
`surname` TEXT,
`name` INTEGER
);
CREATE TABLE `author` (
`book_id` INTEGER,
`person_id` INTEGER,
FOREIGN KEY(`book_id`) REFERENCES book(book_id),
FOREIGN KEY(`person_id`) REFERENCES person(person_id)
);
CREATE TABLE `translator` (
`book_id` INTEGER,
`person_id` INTEGER,
FOREIGN KEY(`book_id`) REFERENCES book(book_id),
FOREIGN KEY(`person_id`) REFERENCES person(person_id)
);
INSERT into book VALUES(1, 'Divine Comedy');
INSERT into person VALUES(1, 'Alighieri', 'Dante');
INSERT into person VALUES(2, 'Binyon', 'Laurence');
INSERT into author VALUES(1, 1);
INSERT into translator VALUES(1, 2);
当我在数据库中查询标题' Divine Comedy'我有这个(某种程度上预期)的结果:
SELECT book.title, person.surname, person.name FROM book, person WHERE book.title='Divine Comedy';
Divine Comedy|Alighieri|Dante
Divine Comedy|Binyon|Laurence
问题是,我如何知道哪个人被选为作者?哪个人被选为翻译?
答案 0 :(得分:0)
此查询不正确;它会对书籍进行过滤,但随后会将其与数据库中所有人员结合使用。
为了只获得那些与某本书有关的人,你必须过滤这种关系:
SELECT book.title, person.surname, person.name
FROM book
JOIN author USING (book_id)
JOIN person USING (person_id)
WHERE book.title = 'Divine Comedy';
SELECT book.title, person.surname, person.name
FROM book
JOIN translator USING (book_id)
JOIN person USING (person_id)
WHERE book.title = 'Divine Comedy';
如果您想在单个查询中获得所有结果,只需合并两个查询:
SELECT book.title, person.surname, person.name, 'author' AS type
FROM book
JOIN author USING (book_id)
JOIN person USING (person_id)
WHERE book.title = 'Divine Comedy'
UNION ALL
SELECT book.title, person.surname, person.name, 'translator' AS type
FROM book
JOIN translator USING (book_id)
JOIN person USING (person_id)
WHERE book.title = 'Divine Comedy';
或者,将两个关系表组合成一个common table expression:
WITH relationship(book_id, person_id, type) AS (
SELECT book_id, person_id, 'author' FROM author
UNION ALL
SELECT book_id, person_id, 'translator' FROM translator
)
SELECT book.title, person.surname, person.name, relationship.type
FROM book
JOIN relationship USING (book_id)
JOIN person USING (person_id)
WHERE book.title = 'Divine Comedy';