2016-08-02 11 views
1

beitreten Ich habe die folgenden drei Tabellen:SQLLite Where-Klausel mit inneren

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)); 

Ich möchte eine Liste aller Bücher erzeugen, und wenn ein Benutzer angemeldet ist, zeigen auch, dass Benutzer Bewertung für dieses Buch .

Case # 1 (Werke): Wenn kein Benutzer angemeldet (user.id nicht gesetzt), nur alle Bücher Liste:

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

Case # 2 (Werke): Wenn Benutzer 2 angemeldet ist in (user.id = 2), listen Sie alle Bücher zusammen mit seinen Bewertungen (falls vorhanden):

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|||| 

Fall # 3 (nicht): wenn Benutzer 1 angemeldet (user.id = 1), liste alle Bücher zusammen mit seinen Rezensionen auf (falls vorhanden):

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|||| 

Problem hier ist, dass Buch 2 eine Überprüfung hat, aber nicht von Benutzer 1, so dass Buch nicht die WHERE-Klausel entspricht.

Wir würden uns über Vorschläge zur Lösung dieses Problems freuen. Entweder durch Ändern des Schemas oder durch Abfragen. Ich benutze SQLAlchemy, so dass ORM auch möglich wäre.

Antwort

2

Sie wollen den Zustand der ON Klausel bewegen:

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

Mit „OR reviews.user_id IS NULL“ Teil Ihrer Abfrage Sie erlauben „verwaiste“ Bücher im Ergebnis zu erscheinen. Sie sollten diese Klausel aus Ihrer Abfrage entfernen oder eine innere Verknüpfung anstelle einer linken Verknüpfung verwenden.