2012-10-16 16 views
5

Mam następującą strukturę:SQL: suma wartości, ale tylko dla różnych identyfikatorów - suma warunkowa?

dzień z wieloma wydarzeniami Typ1 i Typ2, gdzie Typ1 i Typ2 mają kluczy obcych do swoich dni. Typ2 ma również czas trwania.

Teraz chcę policzyć wszystkie zdarzenia typ1, wszystkie zdarzenia typu 2 i sumę czasu trwania typ2.

Przykład Dane:

Dzień:

ID = 1 | Date = yesterday | ... 

Typ1:

ID = 1 | FK_DAY = 1 | ... 

ID = 2 | FK_DAY = 1 | ... 

Typ2:

ID = 1 | FK_DAY = 1 | duration = 10 

ID = 2 | FK_DAY = 1 | duration = 20 

Chcę teraz wynik:

Day.ID = 1 | countTyp1 = 2 | countTyp2 = 2 | sumDurationTyp2 = 30 

Mój problem jest sumą, potrzebuję czegoś takiego jak "suma dla odrębnego typ2.ID" ... Czy ktoś wie, jak to rozwiązać?

Używam coś jak poniżej, ale to oczywiście nie działa tak, jak chcesz:

SELECT day.id, 
    count(DISTINCT typ1.id), 
    count(DISTINCT typ2.id), 
    sum(duration) AS duration 
FROM days 
    LEFT JOIN typ 
      ON day.id = typ1.id 
    LEFT JOIN typ2 
      ON day.id = typ2.id 
GROUP BY day.id; 
+0

Co RDBMS i jaka wersja? – Tobsey

Odpowiedz

13

Moje ogólne podejście do tego celu jest pre-kruszywo każdy stół, przed przystąpieniem .

Po części dlatego, że właściwie nie sumujesz różnych wartości (jeśli każdy z dwóch wierszy miał 10, odpowiedź nadal brzmi: 20).

Ale głównie dlatego, że w rzeczywistości jest to prostsze. Poddytryny wykonują agregację, a łączenie to 1: 1.

SELECT 
    days.id, 
    typ_agg.rows, 
    type2_agg.rows, 
    type2_agg.duration 
FROM 
    days 
LEFT JOIN 
    (SELECT fk_day, COUNT(*) as rows FROM typ GROUP BY fk_day) AS typ_agg 
    ON days.id = typ_agg.fk_day 
LEFT JOIN 
    (SELECT fk_day, COUNT(*) as rows, SUM(duration) as duration FROM typ2 GROUP BY fk_day) AS typ2_agg 
    ON days.id = typ2_agg.fk_day 
+1

. . Mam nadzieję, że jest to przyjęta odpowiedź, ponieważ jest to właściwe podejście. –

+0

Wielkie dzięki, w moim prawdziwym zapytaniu, które jest bardziej złożone, dzięki czemu jest on znacznie czytelniejszy – prom85

0
SELECT day.id, 
    count(DISTINCT typ1.id), 
    count(DISTINCT typ2.id), 
    (select sum(t2.duration) 
    from typ2 t2 
    where t2.id = day.id 
    ) AS duration 
FROM days 
    LEFT JOIN typ 
      ON day.id = typ1.id 
    LEFT JOIN typ2 
      ON day.id = typ2.id 
GROUP BY day.id; 
+0

Wprowadza to dodatkowe podzapytania i uważam, że OP szukał pojedynczego rozwiązania zapytań. Czy twoja odpowiedź oznacza, że ​​nie można jej zapisać jako pojedynczego zapytania? – Yuck

+0

@Yuck - gdzie jest napisane 'single query' lub' bez sub-zapytań'. Dlaczego uważasz, że "pod-zapytania" nie są częścią "pojedynczego zapytania"? * (Jeśli są czymś w rodzaju "pod-czegoś", są częścią tego, a "to" jest pojedynczym zapytaniem ...) * Nie wspominając, że niektóre RDBMS są wyjątkowe przy wydatkowaniu pod-zapytań. – MatBailie

+0

FWIW to nie jest mój downwinter. I przynajmniej w SQL Server, tego typu zapytanie ma (często) surowe kary za wydajność. Nie to, że to jest złe. Właśnie zadawałem pytanie - czy jest jakiś sposób, aby to zrobić bez konieczności ponownej selekcji tabel? – Yuck