如何检查哪个外键可以看到结果

时间:2018-01-31 11:50:39

标签: sqlite foreign-keys

假设我有一个包含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

问题是,我如何知道哪个人被选为作者?哪个人被选为翻译?

1 个答案:

答案 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';