Muszę zaimplementować następujące zapytanie w SQL Server:
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
)
Ale klauzula WHERE..IN zezwala tylko na 1 kolumnę. Jak mogę porównać 2 lub więcej kolumn z innym wewnętrznym SELECT?
sql-server
ala
źródło
źródło
Odpowiedzi:
Możesz utworzyć tabelę pochodną z podzapytania i połączyć tabelę table1 z tą tabelą pochodną:
źródło
Zamiast tego będziesz chciał użyć składni WHERE EXISTS.
źródło
OSTRZEŻENIE DOTYCZĄCE ROZWIĄZAŃ:
WIELE ISTNIEJĄCYCH ROZWIĄZAŃ DAJE NIEPRAWIDŁOWE WYDAJNOŚĆ, JEŚLI WIERSZE NIE SĄ WYJĄTKOWE
Jeśli jesteś jedyną osobą tworzącą tabele, może to nie mieć znaczenia, ale kilka rozwiązań da inną liczbę wierszy wyjściowych z danego kodu, gdy jedna z tabel może nie zawierać unikalnych wierszy.
OSTRZEŻENIE DOTYCZĄCE PROBLEMU:
W PRZYPADKU WIELU KOLUMN NIE ISTNIEJE, UWAŻNIE PRZEMYŚL, CO CHCESZ
Kiedy widzę wejście z dwiema kolumnami, wyobrażam sobie, że oznacza to dwie rzeczy:
Scenariusz 1 jest dość trywialny, po prostu użyj dwóch instrukcji IN.
Zgodnie z większością istniejących odpowiedzi, niniejszym przedstawiam przegląd wspomnianych i dodatkowych podejść do scenariusza 2 (oraz krótką ocenę):
ISTNIEJE (bezpieczne, zalecane dla SQL Server)
Jak zapewnia @mrdenny, EXISTS brzmi dokładnie tak, jak szukasz, oto jego przykład:
LEFT SEMI JOIN (Bezpieczne, zalecane dla dialektów, które go obsługują)
Jest to bardzo zwięzły sposób dołączania, ale niestety większość dialektów SQL, w tym serwer SQL, obecnie go nie obsługuje.
Wiele instrukcji IN (bezpieczne, ale uważaj na powielanie kodu)
Jak wspomniał @cataclysm, użycie dwóch instrukcji IN również może załatwić sprawę, być może nawet przewyższy inne rozwiązania. Jednak należy być bardzo ostrożnym przy powielaniu kodu. Jeśli kiedykolwiek zechcesz wybrać z innej tabeli lub zmienić instrukcję where, istnieje zwiększone ryzyko, że stworzysz niespójności w swojej logice.
Podstawowe rozwiązanie
Rozwiązanie bez duplikacji kodu (uważam, że to nie działa w zwykłych zapytaniach SQL Server)
WEWNĘTRZNE JOIN (technicznie można to zabezpieczyć, ale często się tego nie robi)
Powodem, dla którego nie polecam używania sprzężenia wewnętrznego jako filtru, jest to, że w praktyce ludzie często pozwalają, aby duplikaty w prawej tabeli powodowały duplikaty w lewej tabeli. Co gorsza, czasami sprawiają, że wynik końcowy jest inny, podczas gdy lewa tabela może nie być unikalna (lub nie jest unikalna w wybranych kolumnach). Co więcej, daje Ci możliwość faktycznego wybrania kolumny, której nie ma w lewej tabeli.
Najczęstsze błędy:
ZŁĄCZENIE KOLUMN Z SEPARATOREM (Niezbyt bezpieczne, straszne wykonanie)
Problem funkcjonalny polega na tym, że jeśli użyjesz separatora, który może wystąpić w kolumnie, trudno jest upewnić się, że wynik jest w 100% dokładny. Problem techniczny polega na tym, że ta metoda często powoduje konwersję typów i całkowicie ignoruje indeksy, co skutkuje prawdopodobnie okropną wydajnością. Mimo tych problemów muszę przyznać, że czasami nadal używam go do zapytań ad-hoc na małych zbiorach danych.
Zwróć uwagę, że jeśli kolumny są numeryczne, niektóre dialekty SQL będą wymagały najpierw rzutowania ich na łańcuchy. Uważam, że serwer SQL zrobi to automatycznie.
Podsumowując: jak zwykle w SQL jest wiele sposobów, aby to zrobić, używanie bezpiecznych wyborów pozwoli uniknąć niespodzianek i zaoszczędzić czas i na dłuższą metę.
źródło
Uwaga:
Oracle ignoruje wiersze, w których co najmniej jedna z wybranych kolumn ma wartość NULL. W takich przypadkach prawdopodobnie będziesz chciał użyć NVL -Funktion do odwzorowania NULL na specjalną wartość (która nie powinna znajdować się w wartościach);
źródło
where (colA,colB) in (... some list of tuples...)
ale nie jestem pewien, jakie inne bazy danych robią to samo. Chciałbym wiedzieć.Prosta klauzula EXISTS jest najczystsza
Jeśli masz wiele wierszy w korelacji, wówczas JOIN daje wiele wierszy w wyniku, więc potrzebujesz różnych. Co zwykle sprawia, że ISTNIEJE bardziej wydajne.
Uwaga
SELECT *
z JOIN obejmowałaby również kolumny z tabel ograniczających wierszeźródło
Po co używać GDZIE ISTNIEJE lub POCHODZONE TABELE, skoro można po prostu wykonać zwykłe sprzężenie wewnętrzne:
Jeśli para (CM_PLAN_ID, Individual_ID) nie jest unikalna w tabeli statusów, możesz potrzebować zamiast tego SELECT DISTINCT t. *.
źródło
1.Używanie z
EXISTS
[Średni czas zapytania: 1,42 s]2. Używanie z dwoma wierszami
IN
Klauzula [średni czas zapytania: 0,37 s]3.Używanie z
INNNER JOIN
wzorcem [średni czas zapytania: 2,9 s]Więc wybrałem drugą opcję.
źródło
AND
raczejOR
stwierdzeń niż stwierdzeń.OR
stwierdzenie prawdopodobnie wywoła powielenia. W moim przypadku nie ma żadnych wierszy zawierających to samosrc_id
idest_id
w jednym wierszu. Tak więc w moim przypadku nie dojdzie do duplikacji.Pytanie:
powyższe zapytanie działało dla mnie w mysql. zobacz poniższy link ->
https://www.w3resource.com/sql/subqueries/multiplee-row-column-subqueries.php
źródło
Jeśli chcesz dla jednej tabeli, użyj następującego zapytania
i dane w tabeli, jak następuje
Następnie wypisz w następujący sposób
źródło
id in (1,2) and studentName in ('a','b')
nie jest tym samym, co(id, studentName) in ((1,'a'),(2,'b'))
. Wystarczy pomyśleć o rekordzie mającym id = 2 i name = 'a'. Oczywiście, jeśli identyfikator jest unikalny, efekt jest zmniejszony, ale jeśli identyfikator jest unikalny, nie musimy w ogóle filtrować nazw.Możemy to po prostu zrobić.
źródło
Łączenie kolumn ze sobą w jakiejś formie to „hack”, ale jeśli produkt nie obsługuje łączeń połowicznych dla więcej niż jednej kolumny, czasami nie masz wyboru.
Przykład sytuacji, w której połączenie wewnętrzne / zewnętrzne nie zadziała:
Gdy zapytania nie są z natury trywialne, czasami nie masz dostępu do tabeli podstawowej ustawionej na wykonywanie zwykłych sprzężeń wewnętrznych / zewnętrznych.
Jeśli korzystasz z tego „hackowania”, podczas łączenia pól po prostu upewnij się, że dodałeś wystarczająco dużo separatora między nimi, aby uniknąć błędnych interpretacji, np.
ColA + ":-:" + ColB
źródło
W ten sposób założyłem łatwiej
Mam nadzieję, że to pomoże :)
źródło
CM_PLAN_ID = 45
iIndividual_ID = 3
wtedy wyniki konkatenacji we453
- co jest nie do odróżnienia od przypadkuCM_PLAN_ID = 4
iIndividual_ID = 53
... kłopoty bym myślał45_3
lub,45:3
ale to wciąż nie jest dobre rozwiązanie i oczywiście, jak mówi @mrdenny, indeksy nie będą używane teraz, gdy dokonano transformacji kolumn.Prostym i złym sposobem byłoby połączenie dwóch kolumn za pomocą + lub konkatenacja i utworzenie jednej kolumny.
To byłoby całkiem powolne. Nie może być używany w programowaniu, ale jeśli pytasz tylko o weryfikację, może być użyty.
źródło