Ich muss die folgende Abfrage in SQL Server implementieren:
select *
from table1
WHERE (CM_PLAN_ID,Individual_ID)
IN
(
Select CM_PLAN_ID, Individual_ID
From CRM_VCM_CURRENT_LEAD_STATUS
Where Lead_Key = :_Lead_Key
)
Die WHERE..IN-Klausel erlaubt jedoch nur eine Spalte. Wie kann ich 2 oder mehr Spalten mit einem anderen inneren SELECT vergleichen?
sql-server
ala
quelle
quelle
Antworten:
Sie können aus der Unterabfrage eine abgeleitete Tabelle erstellen und table1 mit dieser abgeleiteten Tabelle verknüpfen:
quelle
Sie sollten stattdessen die WHERE EXISTS-Syntax verwenden.
quelle
WARNUNG ZU LÖSUNGEN:
VIELE BESTEHENDE LÖSUNGEN GEBEN DIE FALSCHE AUSGABE, WENN REIHEN NICHT EINZIGARTIG SIND
Wenn Sie die einzige Person sind, die Tabellen erstellt, ist dies möglicherweise nicht relevant. Mehrere Lösungen geben jedoch eine andere Anzahl von Ausgabezeilen als der betreffende Code an, wenn eine der Tabellen möglicherweise keine eindeutigen Zeilen enthält.
WARNUNG ÜBER DIE PROBLEMSTELLUNG:
IN MIT MEHREREN SPALTEN GIBT ES NICHT, DENKEN SIE SORGFÄLTIG, WAS SIE WOLLEN
Wenn ich ein In mit zwei Spalten sehe, kann ich mir vorstellen, dass es zwei Dinge bedeutet:
Szenario 1 ist ziemlich trivial. Verwenden Sie einfach zwei IN-Anweisungen.
In Übereinstimmung mit den meisten vorhandenen Antworten gebe ich hiermit einen Überblick über die genannten und zusätzlichen Ansätze für Szenario 2 (und eine kurze Beurteilung):
EXISTS (sicher, empfohlen für SQL Server)
Wie von @mrdenny bereitgestellt, klingt EXISTS genau so, wie Sie es suchen. Hier ist sein Beispiel:
LEFT SEMI JOIN (Sicher, empfohlen für Dialekte, die dies unterstützen)
Dies ist eine sehr prägnante Art des Beitritts, aber leider unterstützen die meisten SQL-Dialekte, einschließlich SQL Server, dies derzeit nicht.
Mehrere IN-Anweisungen (sicher, aber Vorsicht vor Codeduplizierungen)
Wie von @cataclysm erwähnt, kann die Verwendung von zwei IN-Anweisungen ebenfalls den Trick ausführen. Vielleicht übertrifft es sogar die anderen Lösungen. Was Sie jedoch sehr vorsichtig sein sollten, ist die Codeduplizierung. Wenn Sie jemals aus einer anderen Tabelle auswählen oder die where-Anweisung ändern möchten, besteht ein erhöhtes Risiko, dass Sie Inkonsistenzen in Ihrer Logik erzeugen.
Grundlösung
Lösung ohne Codeduplizierung (Ich glaube, dies funktioniert nicht in regulären SQL Server-Abfragen)
INNER JOIN (technisch kann es sicher gemacht werden, aber oft wird dies nicht getan)
Der Grund, warum ich die Verwendung eines inneren Joins als Filter nicht empfehle, liegt darin, dass in der Praxis häufig Duplikate in der rechten Tabelle Duplikate in der linken Tabelle verursachen. Und um die Sache noch schlimmer zu machen, wird das Endergebnis manchmal deutlich, während die linke Tabelle möglicherweise nicht eindeutig sein muss (oder in den ausgewählten Spalten nicht eindeutig sein muss). Darüber hinaus haben Sie die Möglichkeit, eine Spalte auszuwählen, die in der linken Tabelle nicht vorhanden ist.
Häufigste Fehler:
KONKATENATION VON SPALTEN MIT SEPARATOR (Nicht sehr sichere, schreckliche Leistung)
Das Funktionsproblem besteht darin, dass es schwierig wird, sicherzustellen, dass das Ergebnis 100% genau ist, wenn Sie ein Trennzeichen verwenden, das in einer Spalte auftreten kann. Das technische Problem besteht darin, dass diese Methode häufig Typkonvertierungen durchführt und Indizes vollständig ignoriert, was zu einer möglicherweise schrecklichen Leistung führt. Trotz dieser Probleme muss ich zugeben, dass ich es manchmal immer noch für Ad-hoc-Abfragen in kleinen Datensätzen verwende.
Wenn Ihre Spalten numerisch sind, müssen Sie sie bei einigen SQL-Dialekten zuerst in Zeichenfolgen umwandeln. Ich glaube, SQL Server wird dies automatisch tun.
Zum Abschluss: Wie üblich gibt es in SQL viele Möglichkeiten, dies zu tun. Wenn Sie sichere Entscheidungen treffen, vermeiden Sie Überraschungen und sparen auf lange Sicht Zeit und Kopfzerbrechen.
quelle
Hinweis:
Oracle ignoriert Zeilen, in denen eine oder mehrere der ausgewählten Spalten NULL sind. In diesen Fällen möchten Sie wahrscheinlich die NVL- Funktion verwenden, um NULL einem speziellen Wert zuzuordnen (der nicht in den Werten enthalten sein sollte).
quelle
where (colA,colB) in (... some list of tuples...)
aber ich bin mir nicht sicher, welche anderen Datenbanken dasselbe tun. Es würde mich interessieren zu wissen.Eine einfache EXISTS-Klausel ist am saubersten
Wenn Sie mehrere Zeilen in der Korrelation haben, gibt ein JOIN mehrere Zeilen in der Ausgabe an, sodass Sie unterschiedliche Zeilen benötigen. Das macht die EXISTS normalerweise effizienter.
Hinweis
SELECT *
mit einem JOIN würde auch Spalten aus den Zeilenbegrenzungstabellen enthaltenquelle
Warum WHERE EXISTS oder DERIVED TABLES verwenden, wenn Sie nur eine normale innere Verknüpfung durchführen können:
Wenn das Paar (CM_PLAN_ID, Individual_ID) in der Statustabelle nicht eindeutig ist, benötigen Sie möglicherweise stattdessen ein SELECT DISTINCT t. *.
quelle
1.Verwenden mit
EXISTS
[Durchschnittliche Abfragezeit: 1,42 s]2.Verwenden mit zwei Zeilen
IN
Klausel [Durchschnittliche Abfragezeit: 0,37 s]3.Verwenden mit
INNNER JOIN
Muster [Durchschnittliche Abfragezeit: 2,9 s]Also entschied ich mich für die zweite Option.
quelle
AND
eherOR
Anweisungen als Anweisungen verwenden.OR
Aussage führt wahrscheinlich zu Überschneidungen. In meinem Fall gibt es keine Zeilen, die dieselbesrc_id
unddest_id
eine einzelne Zeile enthalten. In meinem Fall kommt es also nicht zu Duplikaten.Abfrage:
Die obige Abfrage hat bei mir in MySQL funktioniert. siehe folgenden Link ->
https://www.w3resource.com/sql/subqueries/multiplee-row-column-subqueries.php
quelle
Wenn Sie für eine Tabelle möchten, verwenden Sie die folgende Abfrage
und Tabellendaten wie folgt
Dann wie folgt ausgeben
quelle
id in (1,2) and studentName in ('a','b')
ist total nicht das gleiche wie(id, studentName) in ((1,'a'),(2,'b'))
. Stellen Sie sich einen Datensatz mit id = 2 und name = 'a' vor. Wenn die ID eindeutig ist, wird der Effekt natürlich verringert, aber wenn die ID eindeutig ist, müssen wir überhaupt nicht nach Namen filtern.Wir können das einfach machen.
quelle
Das Verketten der Spalten in irgendeiner Form ist ein "Hack", aber wenn das Produkt keine Semi-Joins für mehr als eine Spalte unterstützt, haben Sie manchmal keine Wahl.
Beispiel dafür, wo eine innere / äußere Verbindungslösung nicht funktionieren würde:
Wenn die Abfragen nicht trivialer Natur sind, haben Sie manchmal keinen Zugriff auf die Basistabelle, um regelmäßige innere / äußere Verknüpfungen durchzuführen.
Wenn Sie diesen "Hack" verwenden, müssen Sie beim Kombinieren von Feldern genügend Trennzeichen dazwischen einfügen, um Fehlinterpretationen zu vermeiden, z
ColA + ":-:" + ColB
quelle
Ich habe auf diese Weise leichter gegründet
Ich hoffe das hilft :)
quelle
CM_PLAN_ID = 45
undIndividual_ID = 3
dann Verkettung führt453
- was nicht von dem Fall zu unterscheiden ist, woCM_PLAN_ID = 4
undIndividual_ID = 53
... um Ärger zu bitten, hätte ich gedacht45_3
oder45:3
aber es ist noch nicht eine schöne Lösung und natürlich als @mrdenny sagt Indizes wird nicht jetzt genutzt werden , dass eine Transformation statt auf den Säulen genommen.Ein einfacher und falscher Weg wäre, zwei Spalten mit + zu kombinieren oder zu verketten und eine Spalte zu erstellen.
Das wäre natürlich ziemlich langsam. Kann nicht in der Programmierung verwendet werden, aber wenn Sie nur nach einer Überprüfung fragen, kann etwas verwendet werden.
quelle