2012-10-16 18 views
5

. Typ2 ayrıca süreye sahiptir.SQL: bir değerin toplamı, ancak yalnızca farklı kimlikleri için - koşullu toplam?</p> <p>Gün Typ1 ve TYP2, Typ1 birden olaylarla ve kendi günlere yabancı anahtarlara sahip TYP2: Ben yapısı şu var

Şimdi bütün Typ1 olayları, bütün TYP2 etkinliklerle TYP2 süresinin toplamı saymak istiyorum.

Örnek Verileri:

Gün:

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 

şimdi sonucunu istiyorum:

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

Sorunum toplamı, "farklı tip2.ID için toplam" gibi bir şeye ihtiyacım var ... Herkes bunu çözmek için bir yol biliyor mu? katılmadan önce,

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; 
bu Benim genel yaklaşım ön agrega her tablo için
+0

Ne RDBMS ve hangi sürümünün? – Tobsey

cevap

13

geçerli:

ben Aşağıdaki gibi bir şey kullanıyorum, ama tabii ki bu benim istediğim gibi çalışmıyor .

Parçalı aslında (iki sıranın her 10 olsaydı, cevap yine 20 olan) farklı değerleri toplayarak etmediklerinden.

Ama çoğunlukla aslında basit bu şekilde çünkü

. Alt sorgular kümelenmeyi yapar, daha sonra birleştirmeler 1: 1'dir.

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

olsa o intereseted ediyorum için ... arıyordu budur. . Umarım kabul edilen cevaptır, çünkü doğru yaklaşımdır. çok daha karmaşıktır benim gerçek sorguda, bu gerçekten çok daha okunabilir hale getirir –

+0

Teşekkür – 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

Bu, ek alt sorgular sunar ve OP'nin tek bir sorgu çözümü aradığına inanıyorum. Cevabınız, tek bir sorgu olarak yazılmayacağı anlamına mı geliyor? – Yuck

+0

@Yuck - "Tek sorgu" veya "alt sorgular" dır. Neden 'alt sorguları' tek bir sorgunun bir parçası olarak düşünmüyorsunuz? * (Onlar iseniz bir 'alt' şeyin, onlar ... Onun 'tek sorgu 'onun bir parçası, ve) * Belirli RDBMS alt sorguları dışarı sokmaksızın olağanüstü olduğunu cabası. – MatBailie

+0

FWIW bu benim downvote değil. Ve en azından SQL Server'da, bu sorgu türü (genellikle) ciddi performans cezalarına sahiptir. Bu yanlış değil. Sadece soruyu soruyordum - ilgili tabloları alt seçmeden yapmanın bir yolu var mı? – Yuck