3 Stimmen

Hilfe beim Konvertieren von Unterabfragen in Abfragen mit Joins

Ich stecke in einer Abfrage mit einer Verknüpfung fest. Die Website des Kunden läuft mit mysql4, so dass eine Subquery keine Option ist. Meine Versuche, mit einer Verknüpfung umzuschreiben sind nicht zu gut gehen.

Ich muss alle in der Tabelle "Auftragnehmer" aufgeführten Auftragnehmer auswählen, die nicht in der Tabelle "Auftragnehmer2Label" mit einer bestimmten Label-ID und Bezirks-ID enthalten sind. Sie könnten jedoch in der Tabelle contractors2label mit anderen IDs für Bezeichnung und Bezirk aufgeführt sein.

Tabelle: Auftragnehmer

cID (primär, automatische Nummer)
Unternehmen (varchar)
...usw...

Tabelle: contractors2label

cID
labelID
countyID
psID

Diese Abfrage mit einer Unterabfrage funktioniert:

SELECT company, contractors.cID
   FROM contractors
   WHERE contractors.complete = 1
   AND contractors.archived = 0
   AND contractors.cID NOT IN (
     SELECT contractors2label.cID FROM contractors2label
        WHERE labelID <> 1 AND countyID <> 1
   )

Ich dachte, dass diese Abfrage mit einer Verknüpfung das Äquivalent sein würde, aber sie liefert keine Ergebnisse. Eine manuelle Überprüfung der Daten zeigt, dass ich 34 Zeilen erhalten sollte, was die obige Unterabfrage auch liefert.

SELECT company, contractors.cID
   FROM contractors 
   LEFT OUTER JOIN contractors2label ON contractors.cID = contractors2label.cID
   WHERE contractors.complete = 1
   AND contractors.archived = 0
   AND contractors2label.labelID <> 1
   AND contractors2label.countyID <> 1
   AND contractors2label.cID IS NULL

0 Stimmen

+1 für neu hier zu sein, und die Verwaltung eine richtig formatierte Frage mit einer guten Beschreibung Ihres Problems einschließlich Beispielcode zur Verfügung zu stellen :)

2voto

Peter Lang Punkte 52229

Wenn Sie eine LEFT JOIN müssen Sie alle Bedingungen der JOIN in die ON Klausel.

In Ihrem Beispiel erhalten Sie NULL für links verbundene Spalten, die nicht existieren, aber Sie vergleichen sie dann wieder mit Werten ( <> 1 ), was nicht funktioniert.

SELECT c.company, c.cID
   FROM contractors c
   LEFT JOIN contractors2label c2
          ON ( c2.cID = c.cID AND c2.labelID <> 1 AND c2.countyID <> 1 )
   WHERE c.complete = 1
   AND c.archived = 0
   AND c2.cID IS NULL

Übrigens: Die Verwendung von Aliasen (wie c in meinem Beispiel) erleichtert das Lesen und Schreiben Ihrer Abfragen.

0 Stimmen

OK, ich hätte nicht so schnell springen sollen. Wenn ich es an meine App anschließe, funktioniert es tatsächlich nicht.

0 Stimmen

@Tim: Können Sie die Probleme beschreiben, mit denen Sie konfrontiert sind?

0 Stimmen

Mein Fehler ... meine Logik ist verkehrt. Ihre Abfrage wird mir geben, was ich brauche, wenn ich ON ( c2.cID = c.cID AND c2.labelID = 1 AND c2.countyID = 1 ) ändere. Übrigens denke ich, dass die Antwort von @Nick unten auch funktioniert, mit der Änderung von <> zu =.

2voto

Nick Craver Punkte 609016

Wenn Sie eine Where-Klausel mit Hilfe der Spalten einer Tabelle einschränken, die LEFT verbunden sind, entfernen Sie effektiv die LEFT OUTER Teil der Verknüpfung, da Sie nach Spalten filtern, die vorhanden sein müssen. Versuchen Sie stattdessen Folgendes:

SELECT company, contractors.cID
   FROM contractors 
   LEFT OUTER JOIN contractors2label 
       ON (contractors.cID = contractors2label.cID
           AND contractors2label.labelID <> 1
           AND contractors2label.countyID <> 1)
   WHERE contractors.complete = 1
   AND contractors.archived = 0
   AND contractors2label.cID IS NULL

Dadurch wird die Einschränkung als Teil der Verknüpfung durchgeführt, so dass Nullen in der größeren Abfrage weiterhin verwendet werden können.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X