2014-12-10 9 views
17

Ich bin verwirrt von einer SQL-Abfrage, und ehrlich gesagt, es ist eines dieser Dinge, die ich nicht einmal sicher bin, wie man googelt. Also StackOverflow.Warum verursacht diese Unterabfrage KEINEN Fehler?

Ich habe was ich denke, ist eine einfache Abfrage.

SELECT Id 
FROM Customer 
WHERE Id IN (SELECT Id from @CustomersWithCancelledOrders) 

Hier ist, wo ich die Seltsamkeit finde. In der Tabellenvariable @CustomersWithCancelledOrders gibt es keine Spalte namens Id. Aber es gibt keinen Fehler.

Daraus ergeben sich die IDs für alle Kunden. Jeder einzelne. Was offensichtlich den Punkt zunichte macht, eine Unterabfrage überhaupt zu machen.

Es ist wie seine Verwendung der ID-Spalte aus der äußeren Tabelle (Kunden), aber ich verstehe nicht, warum es das tun würde. Gibt es jemals einen Grund, warum du das willst? Fehle ich etwas unglaublich Offensichtliches?

SQLFiddle der Seltsamkeit. Es ist nicht die beste SQL-Fiddle, da ich keine Möglichkeit gefunden habe, mehrere Ergebnismengen auf dieser Website zurückzugeben, aber es zeigt, wie ich das Problem übersprungen habe.

Ich denke, was ich suche ist ein Name für die "Funktion" oben, eine Art von Informationen darüber, warum es tut, was es tut und was die falsche Abfrage tatsächlich bedeutet.


Ich habe die obige Frage aktualisiert, um ein etwas besseres Beispiel zu verwenden. Es ist immer noch erfunden, aber es ist näher an dem Skript, das ich schrieb, als ich tatsächlich auf das Problem stieß.


Nach einigen Lesung am korrelierte Unterabfragen zu tun, es sieht aus wie meine Tippfehler (die falsche Id-Spalte in der Unterabfrage) ändert sich das Verhalten der Unterabfrage.

Anstatt die Ergebnisse der Unterabfrage einmal auszuwerten und diese Ergebnisse dann als eine Menge zu behandeln (was ich beabsichtigte), wertet sie die Unterabfrage für jede Zeile in der äußeren Abfrage aus.

Dies bedeutet, dass die Unterabfrage für jede Zeile zu einer Reihe unterschiedlicher Ergebnisse ausgewertet wird und diese Ergebnismenge garantiert die Kunden-ID dieser Zeile enthält. Die Unterabfrage gibt eine Menge zurück, die aus der Nummer der Zeile besteht, die X Mal wiederholt wird, wobei X die Anzahl der Zeilen in der Tabellenvariablen ist, aus der ausgewählt wird.

...

Es ist wirklich schwer, eine kurze Beschreibung der mein Verständnis der Frage aufzuschreiben. Es tut uns leid. Ich denke aber, dass ich jetzt gut bin.

+0

Zufällig, schwer zu sagen, ob Sie neu sind oder einen gültigen Fall vereinfacht haben, aber die meiste Zeit sollten Sie Tabellen beitreten, anstatt eine Unterabfrage zu verwenden. – JamesRyan

+3

Der Fachbegriff, nach dem Sie suchen, ist eine korrelierte Unterabfrage. – Brandon

+0

@JamesRyan Ich habe gestern eine schnelle Abfrage geschrieben und zufälligerweise versehentlich eine UPDATE-Abfrage ähnlich der obigen geschrieben. Die Verwendung der äußeren ID in der Unterabfrage war ein Tippfehler, und ich war sehr überrascht, als es alle Datensätze in der Tabelle anstelle der von mir beabsichtigten Teilmenge aktualisierte. –

Antwort

36

Ihr beabsichtigtes Verhalten, weil Sie in einer Unterabfrage auf die Spaltennamen der 'äußeren Abfragen' zugreifen können. Das bedeutet, dass Sie die ID aus der Tabelle in der Unterabfrage verwenden können und die Abfrage daher die Verwendung der ID annimmt.

Aus diesem Grund sollten Sie sich bei der Arbeit mit Unterabfragen mit Aliasen oder vollständig qualifizierten Namen qualifizieren.

Zum Beispiel; Besuche
http://support.microsoft.com/kb/298674

+0

Das klärt das Verhalten wie beabsichtigt, was ich annahm. Was bedeutet die Abfrage eigentlich? Finden Sie alle Id-Werte innerhalb der Tabelle, wo der Id-Wert in der Menge der Werte ist, die von? –

+8

Die Abfrage bedeutet im Grunde Folgendes: 'SELECT ID FROM Tabelle WHERE ID IN (SELECT Tabelle.Id FROM OtherTable)' Deshalb gibt es alles zurück, solange es irgendwelche Zeilen in OtherTable gibt. Es wählt alle Table.Id aus der Unterabfrage aus, wenn Zeilen in der Unterabfrage vorhanden sind. Versuchen Sie, die Einfügung in CustomerMap in Ihrem Geigenbeispiel zu kommentieren. –

12
SELECT ID 
FROM [Table] 
WHERE ID IN (SELECT OtherTable.ID FROM OtherTable) 

Dies wird einen Fehler erzeugen. Wie Allan S. Hanses sagte, können Sie in der Unterabfrage Spalten aus der Hauptabfrage verwenden.

Sehen Sie dieses Beispiel

SELECT ID 
FROM [Table] 
WHERE ID IN (SELECT ID) 
1

Die Abfrage ist eine korrelierte Unterabfrage und wird am häufigsten verwendet, um die Ergebnisse der äußeren Abfrage auf einer von der Unterabfrage zurück Spalte basierte zu begrenzen; daher das "Korrelierte". In diesem Beispiel ist die ID in der inneren Abfrage tatsächlich die ID aus der Tabelle in der äußeren Abfrage. Dies macht die Abfrage gültig, liefert aber wahrscheinlich keine nützlichen Ergebnisse, da sie nicht tatsächlich zwischen den äußeren und inneren Abfragen korreliert.

Verwandte Themen