Frage

Ich versuche, eine Abfrage zu erstellen, die eine Spalte angibt, ob ein Benutzer ein Dokument heruntergeladen umfassen werden. Ich habe eine Tabelle HasDownloaded mit den folgenden Spalten genannt: id, DocumentID, memberID. Herausfinden, ob ein Benutzer ein spezifische heruntergeladen Dokument ist einfach; aber ich brauche eine Abfrage zu erzeugen, wo die Ergebnisse wie folgt aussehen:

name              id
----------------------
abc               NULL
bbb               2
ccc               53
ddd               NULL
eee               13

Die ID ist nicht wirklich wichtig; was ich bin interessiert, ist, ob das Dokument heruntergeladen wurde (ist es NULL oder nicht).

Hier ist meine Abfrage:

SELECT Documents.name, HasDownloaded.id FROM Documents
LEFT JOIN HasDownloaded ON HasDownloaded.documentID = Documents.id
WHERE HasDownloaded.memberID = @memberID

Das Problem ist, wird dies nur Werte zurück, wenn ein Eintrag für den angegebenen Benutzer in der HasDownloaded Tabelle existiert. Ich möchte diese einfach halten und nur haben Einträge in HasDownloaded für Dokumente, die wurde heruntergeladen. Also, wenn Benutzer 1 abc heruntergeladen hat, bbb und ccc, ich will noch ddd und eee in der resultierenden Tabelle zeigen, nur mit der ID als NULL. Aber die WHERE-Klausel nur gibt mir für welche Werte Einträge vorhanden.

ich nicht viel von einem SQL-Experte bin - gibt es ein Operator, der mir geben wird, was ich hier will? Sollte ich einen anderen Ansatz? Oder ist das unmöglich?

War es hilfreich?

Lösung

Bewegen Sie die Bedingung in der WHERE-Klausel in die Join-Bedingung.

SELECT Documents.name, HasDownloaded.id FROM Documents
LEFT JOIN HasDownloaded ON HasDownloaded.documentID = Documents.id 
  AND HasDownloaded.memberID = @memberID 

Dies ist notwendig, wenn Sie auf eine links beziehen mögen beitreten-ed Tabelle in dem, was sonst die WHERE-Klausel wäre.

Andere Tipps

WHERE HasDownloaded.memberId IS NULL OR HasDownloaded.memberId = @memberId

wäre der normale Weg, das zu tun. Einige würden verkürzen Sie es an:

WHERE COALESCE(HasDownloaded.memberId, @memberId) = @memberId

Sie können, wie Matt B. zeigt, tun Sie es in Ihrer JOIN-Bedingung - aber ich denke, das ist viel wahrscheinlicher, Leute zu verwirren. Wenn Sie nicht verstehen, warum es um die Klausel JOIN funktioniert bewegt, dann würde ich stark davon vorschlagen bleiben weg.

@ Mark: Ich verstehe, warum die Syntax funktioniert JOIN, aber danke für die Warnung. Ich glaube Ihr Vorschlag intuitiver ist. Ich war gespannt, was effizienter war. Also lief ich einen schnellen Test (das war eher simpel, ich habe Angst, über nur 14 Zeilen und 10 Versuche):

In der JOIN-Bedingung:

AND HasDownloaded.memberID = @memberID
  • Client Bearbeitungszeit: 4.6
  • Gesamtausführungszeit: 35.5
  • Wartezeit auf Server-Antworten: 30,9

In der WHERE-Klausel:

WHERE HasDownloaded.memberId IS NULL OR HasDownloaded.memberId = @memberId
  • Client Verarbeitungszeit: 7,7
  • Gesamtausführungszeit: 27.7
  • Wartezeit auf Server-Antworten: 22.0

Es ist wie die WHERE-Klausel aussieht, ist immer so etwas effizienter. Interessant! Noch einmal vielen Dank an Sie beide für Ihre Hilfe.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top