2017-12-01 172 views
8

Mam tabeli:Czy można łączyć grupy według, posiadania i sumy?

------------------------ 
|id|p_id|desired|earned| 
------------------------ 
|1 | 1 | 5 | 7 | 
|2 | 1 | 15 | 0 | 
|3 | 1 | 10 | 0 | 
|4 | 2 | 2 | 3 | 
|5 | 2 | 2 | 3 | 
|6 | 2 | 2 | 3 | 
------------------------ 

muszę dokonać pewnych obliczeń, i spróbować zrobić to w jednym nie bardzo złożonego wniosku, inaczej wiem, jak go obliczyć z liczby żądań. I muszą zaowocować stół jak następuje:

--------------------------------------------------------- 
|p_id|total_earned| AVG |  Count  | SUM | 
| |   | (desired)|(if earned != 0)|(desired)| 
--------------------------------------------------------- 
| 1 |  7  |  10 |  1  | 30 | 
| 2 |  9  |  2 |  3  | 6 | 
--------------------------------------------------------- 

zbudować tak daleko:

SELECT p_id, SUM(earned), AVG(desired), Sum(desired) 
FROM table GROUP BY p_id 

Ale nie mogę dowiedzieć się, jak obliczyć liczbę zgrupowanych rekordów z warunkami. Mogę uzyskać ten numer pod numerem HAVING, ale w oddzielnym żądaniu.

Jestem prawie pewien, co SQL powinien mieć tę moc.

+0

używam PostgreSQL, ale szukać uniwersalnego rozwiązania. –

Odpowiedz

12

Można użyć do tego wyrażenia CASE.

Spróbuj tego,

SELECT p_id 
    ,SUM(earned) AS total_earned 
    ,AVG(desired) AS avg_desired 
    ,COUNT(CASE WHEN Earned!=0 THEN 1 END) AS earned_count 
    ,SUM(desired) AS sum_desired 
FROM table 
GROUP BY p_id; 
3

Masz prawie gotowe zapytanie wystarczy dodać agregację warunkową z pomocą case ekspresji za zarobione count

SELECT 
      p_id, 
      SUM(earned) [total_earned], 
      AVG(desired) [desired], 
      SUM(CASE WHEN earned <> 0 THEN 1 ELSE 0 END) [COUNT], 
      SUM(desired) [SUM] FROM <table> 
GROUP BY p_id 

Wynik

p_id total_earned desired COUNT SUM 
1  7    10  1  30 
2  9    2   3  6 
+0

To jest niestandardowa SQL –

+0

Niepoprawna składnia PostgreSQL (lub standardowego SQL). –

3

Krótszy alternatywnej to CASE to

SELECT p_id, 
    SUM(earned) AS total_earned, 
    AVG(desired) AS average_desired, 
    COUNT(earned != 0 OR NULL) AS earned_count, 
    SUM(desired) AS sum_desired 
FROM table GROUP BY p_id; 

ponieważ NULL s nie są zliczane.