JOIN dwa wyniki instrukcji SELECT


174

Czy można połączyć wyniki 2 SELECTinstrukcji sql w jednej instrukcji? Mam bazę zadań, w której każdy rekord jest osobnym zadaniem, z terminami (a PALT, który jest tylko liczbą INTdni od początku do terminu. AgeTo również INTliczba dni.)

Chcę mieć tabelę, w której każda osoba ma w tabeli, liczbę zadań, które mają i liczbę LATEzadań, które mają (jeśli są).

Mogę łatwo uzyskać te dane w oddzielnych tabelach, na przykład:

SELECT ks, COUNT(*) AS '# Tasks' FROM Table GROUP BY ks

zwracanie danych takich jak:

ks        # Tasks
person1   7
person2   3

a potem mam:

SELECT ks, COUNT(*) AS '# Late' FROM Table WHERE Age > Palt GROUP BY ks

która zwraca:

ks        # Late
person1   1
person2   1

Chcę połączyć wyniki tych dwóch selectstwierdzeń (przez KS)

Staram się unikać używania tabel tymczasowych, ale jeśli jest to jedyny praktyczny sposób, aby to zrobić, chciałbym dowiedzieć się więcej o używaniu tabel tymczasowych w ten sposób.

Próbowałem też zrobić jakieś count()wiersze, które spełniają warunek, ale nie mogłem też wymyślić, jak to zrobić. Jeśli to możliwe, to też by działało.

Uzupełnienie: Niestety, chcę mieć moje wyniki kolumn KS, TasksorazLate

KS        # Tasks   # Late
person1   7         1
person2   3         1
person3   2         0  (or null)

Dodatkowo chcę, żeby ktoś się pojawił, nawet jeśli nie ma spóźnionych zadań.

SUM(CASE WHEN Age > Palt THEN 1 ELSE 0 END) Late
działa dobrze, dzięki za tę odpowiedź!

Dwie instrukcje wyboru również działają, a LEFT JOINłączenie ich również działa, a teraz rozumiem, jak łączyć wiele selectw ten sposób


Nie podałeś przykładu oczekiwanego wyniku. Niektóre odpowiedzi są zatem konkatenacją wyników. Niektórzy dołączają. Który chcesz?
Phil

Przepraszam, chcę, aby moje wyniki miały kolumny dla KS, Zadania i Spóźnione KS # Zadania # Spóźniona osoba1 7 1 osoba2 3 1 osoba3 2 0 (lub null) Dodatkowo chcę, aby osoba pojawiła się, nawet jeśli nie ma spóźnionych zadań . Obecnie osiąga się to za pomocą metody dwóch instrukcji select z LEFT JOIN (w przeciwieństwie do sugerowanego INNER JOIN, który działa, ale nie pokazuje osób bez późnych zadań, ponieważ nie istnieją w drugim SELECT Również osiąganie tego z późnym kolumna to SUMA (CASE WHEN Age> Palt THEN 1 ELSE 0 END) Late
sylverfyre

Odpowiedzi:


264
SELECT t1.ks, t1.[# Tasks], COALESCE(t2.[# Late], 0) AS [# Late]
FROM 
    (SELECT ks, COUNT(*) AS '# Tasks' FROM Table GROUP BY ks) t1
LEFT JOIN
    (SELECT ks, COUNT(*) AS '# Late' FROM Table WHERE Age > Palt GROUP BY ks) t2
ON (t1.ks = t2.ks);

1
Działa to dobrze, chociaż nie określiłem, że chcę LEFT JOIN, aby rekordy były wyświetlane, nawet jeśli mają 0 późnych zadań.
sylverfyre

Zaakceptowałem tę odpowiedź, ponieważ odpowiada na pytanie, które zadałem najlepiej, i jest sformatowana jako świetne odniesienie do instrukcji JOINing SELECT :)
sylverfyre

Doskonała odpowiedź, ale czy ktoś może powiedzieć, czy tego typu „rozwiązanie” jest uważane za drogie, czy po prostu zależy od tego, do czego go używasz?
petrosmm

71

Spróbuj czegoś takiego:

SELECT 
* 
FROM
(SELECT ks, COUNT(*) AS '# Tasks' FROM Table GROUP BY ks) t1 
INNER JOIN
(SELECT ks, COUNT(*) AS '# Late' FROM Table WHERE Age > Palt GROUP BY ks) t2
ON t1.ks = t2.ks

4
Nie udało mi się uzyskać akceptowanej odpowiedzi, ale to działało świetnie dla moich potrzeb. Dzięki.
benvenker

Działał jak urok. Jeśli o mnie chodzi, to powinna być akceptowana odpowiedź. Dzięki.
nocdib

Pracował dla mnie! Dzięki! Próbowałem też używać wielu zapytań (wiele połączeń) i również działa świetnie. Jeśli ktoś się zastanawia, możesz po prostu dodać więcej JOIN po ostatnim „ON” w przykładzie i nadal używać sekwencji: ON .... X JOIN (QUERY N -1) ON Y = ZX JOIN (QUERY N) ON Y = Z
cesarmart

43

Zastosowanie UNION:

SELECT ks, COUNT(*) AS '# Tasks' FROM Table GROUP BY ks
UNION
SELECT ks, COUNT(*) AS '# Late' FROM Table WHERE Age > Palt GROUP BY ks

Lub UNION ALLjeśli chcesz duplikaty:

SELECT ks, COUNT(*) AS '# Tasks' FROM Table GROUP BY ks
UNION ALL
SELECT ks, COUNT(*) AS '# Late' FROM Table WHERE Age > Palt GROUP BY ks

3
Wynik Union lub Union All będzie miał tylko 2 kolumny. Gdzie chce 3 z nich
SurajS

14

Jeśli Wiek i Palt są kolumnami w tej samej tabeli, możesz policzyć (*) wszystkie zadania i zsumować tylko te późne, jak poniżej:

select ks,
       count(*) tasks,
       sum(case when Age > Palt then 1 end) late
  from Table
 group by ks

1
To jest DOKŁADNIE to, czego chciałem, ale nie wiedziałem, jak tego szukać. Nie pomyślałem o użyciu SUMA (CASE) - dzięki.
sylverfyre

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.