带有内连接的SQLLite Where子句

时间:2016-08-02 11:34:32

标签: sql sqlite

我有以下三个表:

CREATE TABLE users (
    id INTEGER NOT NULL, 
    name TEXT NOT NULL, 
    PRIMARY KEY (id));

CREATE TABLE books (
    id INTEGER NOT NULL, 
    name TEXT NOT NULL, 
    PRIMARY KEY (id));

CREATE TABLE reviews (
    id INTEGER NOT NULL, 
    user_id INTEGER, 
    book_id INTEGER, 
    score INTEGER NOT NULL, 
    PRIMARY KEY (id), 
    FOREIGN KEY(user_id) REFERENCES users (id), 
    FOREIGN KEY(book_id) REFERENCES books (id));

我想生成所有图书的列表,如果用户已登录,还会显示用户查看该图书的分数。

案例#1(有效): 如果没有用户登录(user.id未设置),只需列出所有书籍:

sqlite> SELECT * FROM books;
id|name
1|Life of Pi
2|The Hobbit
3|Catch 22

案例#2(有效): 如果用户2已登录(user.id = 2),请列出所有书籍及其评论(如果有):

sqlite> SELECT * FROM books LEFT OUTER JOIN reviews on books.id =
reviews.book_id WHERE reviews.user_id = 2 OR reviews.user_id IS NULL;
id|name|id|user_id|book_id|score
1|Life of Pi|2|2|1|5
2|The Hobbit|3|2|2|2
3|Catch 22||||

案例#3(失败): 如果用户1已登录(user.id = 1),请列出所有书籍及其评论(如果有):

sqlite> SELECT * FROM books LEFT OUTER JOIN reviews on books.id =
reviews.book_id WHERE reviews.user_id = 1 OR reviews.user_id IS NULL;
id|name|id|user_id|book_id|score
1|Life of Pi|1|1|1|3
3|Catch 22||||

问题在于,第2册有一篇评论,但没有来自用户1,因此该书与WHERE条款不匹配。

欢迎任何有关如何解决此问题的建议。通过更改架构或我的查询。我正在使用SQLAlchemy,因此使用ORM也是可能的。

2 个答案:

答案 0 :(得分:2)

您希望将条件移至ON子句:

SELECT *
FROM books b LEFT OUTER JOIN
     reviews r
     ON b.id = r.book_id AND r.user_id = 1;

答案 1 :(得分:0)

如果您的查询中包含“OR reviews.user_id IS NULL”,则允许“孤儿”图书出现在结果中。您应该从查询中删除此子句,或使用内部联接而不是左联接。