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.