2010-03-03 8 views
5

könnte der Titel ein wenig verwirrend sein, lassen Sie mich erklären,;) Ich habe 3 Tabellen:Wie man nicht existierende Artikel auflistet?

[names] 
n_id;name 
1;Jeff 
2;Adam 

[books] 
b_id;title 
1;Book1 
2;Book2 

[read] 
n_id;b_id 

Die Tabelle [ lesen] ist eine Tabelle mit Lese Bücher. wenn Adam liest "Book1" das Element in [lesen] sieht wie folgt aus:

2;1 

so weit, so gut. Nun, gibt es eine Möglichkeit zu wissen, welche Bücher nicht von einer Person gelesen wurden? Wir wissen, dass nur Adam ein Buch „Book1“ lesen, so dass die Abfrage ausgeben sollte etwas wie folgt aus:

n_id;name;b_id;title 
1;Jeff;1;Book1 
1;Jeff;2;Book2 
2;Adam;2;Book2 

ist es möglich, dies in 1 Abfrage tun oder muss ich etwas scripting?

Antwort

2

können Sie ein CROSS JOIN verwenden, um alle möglichen Kombinationen von names und books und dann ein LEFT JOIN auf read mit IS NULL Reihen entfernen verwenden zu bekommen, die es gibt.

Die LEFT JOIN kehrt NULL für alle verknüpften Spalten, wo keine Zeilen vorhanden sind, so überprüfen, ob r.n_id IS NULL diese Zeilen entfernt, wo die Verknüpfung tatsächlich Zeilen in read gefunden.

SELECT n.n_id, n.name, b.b_id, b.title 
FROM names n 
CROSS JOIN books b 
LEFT JOIN read r ON (r.n_id = n.n_id AND r.b_id = b.b_id) 
WHERE r.n_id IS NULL 
1

Sie benötigen ein Cross Join alle Paare von name vs book zu erzeugen, und dann mit dem read Tisch sitzen und prüfen, wo die nicht beitreten.

SELECT names.n_id, names.name, books.b_id, books.title 
FROM names 
CROSS JOIN books 
LEFT JOIN read 
ON names.n_id = read.n_id AND books.b_id = read.b_id 
WHERE read.n_id IS NULL 
1

Sie ein kartesische zwischen Namen und Büchern verbinden tun würde alle möglichen Namen/Buch Kombinationen zu erhalten, dann minus diejenigen, die gelesen wurden:

SELECT n_id, b_id 
FROM names, books 
MINUS 
SELECT n_id, b_id 
FROM read 

andere vorgeschlagen haben dabei ein Quer zu verbinden und eine linke Verbindung, die auch perfekt funktionieren würde. Vielleicht möchte ich beide versuchen zu sehen, was in einem realen Szenario schneller ist - ich vermute, dass die Linke sich mit anderen verbindet, wäre schneller, aber nicht wirklich sicher.

0

Ihre Frage war: „Gibt es eine Möglichkeit zu wissen, welche Bücher von eine Person lesen werent?“ Aber Ihre Beispielabfrageergebnisse zeigten die Antwort auf die Frage "Gibt es eine Möglichkeit zu wissen, welche Bücher nicht von allen gelesen wurden?"

Wenn Sie wirklich nur auf der Suche die Abfrage für eine bestimmte Person zu laufen, sollte wie folgt funktionieren:

SELECT b_id, title 
FROM books --You said you're just looking for books 
WHERE b_id NOT IN 
    (SELECT b_id 
    FROM read 
    WHERE n_id = @names_id) --pass in the names_id as a parameter 
Verwandte Themen