2015-04-29 14 views
9

Mam 2 tabeleDołącz samej tabeli dwukrotnie liczyć w różnych kolumn

A 
+----+-------+ 
| Id | User | 
+----+-------+ 
| 1 | user1 | 
| 2 | user2 | 
| 3 | user3 | 
+----+-------+ 

B 
+----+--------+------+ 
| Id | UserId | Type | 
+----+--------+------+ 
| 1 |  1 | A | 
| 2 |  1 | B | 
| 3 |  1 | C | 
| 4 |  2 | A | 
| 5 |  2 | B | 
| 6 |  2 | C | 
| 7 |  3 | A | 
| 8 |  3 | C | 
+----+--------+------+ 

UserId is FK from table A.Id 

Próbuję uzyskać liczbę każdego rodzaju i typu permutacje jak niżej z pojedynczego zapytania SQL. (np. liczba A^B oznacza liczbę użytkowników, którzy mają typ A i B)

+---------+---------+---------+-----------+-----------+-----------+-------------+ 
| Count A | Count B | Count C | Count A^B | Count A^C | Count B^C | Count A^B^C | 
+---------+---------+---------+-----------+-----------+-----------+-------------+ 
|  3 |  2 |  3 |   2 |   3 |   2 |   2 | 
+---------+---------+---------+-----------+-----------+-----------+-------------+ 

Lub osobne zapytanie dla każdej liczby permutacji.

Próbowałem wykonać poniższe zapytanie, aby osobno odliczyć typ A i B i nie zadziałało.

SELECT count(b1.type) AS count_a, count(b2.type) AS count_b FROM A 
JOIN B on A.id = B.user_id 
WHERE b1.type = 'A' or b2.type = 'B' 
GROUP BY A.id; 

+---------+---------+ 
| Count A | Count B | 
+---------+---------+ 
|  3 |  2 | 
+---------+---------+ 
+0

Nie jestem pewien, gdzie znajdują się dwie tabele lub co "^" reprezentuje –

+0

@ ExploxPills, które są tylko aliasami kolumn. –

+0

Zaktualizowałem pytanie. Mam nadzieję, że wyjaśni to lepiej. Zasadniczo liczba A^B oznacza liczbę użytkowników, którzy mają typ A i B –

Odpowiedz

7

Można napisać:

select count(case when "Types" @> array['A'] then 1 end) as "COUNT A", 
     count(case when "Types" @> array['B'] then 1 end) as "COUNT B", 
     count(case when "Types" @> array['C'] then 1 end) as "COUNT C", 
     count(case when "Types" @> array['A','B'] then 1 end) as "COUNT A^B", 
     count(case when "Types" @> array['A','C'] then 1 end) as "COUNT A^C", 
     count(case when "Types" @> array['B','C'] then 1 end) as "COUNT B^C", 
     count(case when "Types" @> array['A','B','C'] then 1 end) as "COUNT A^B^C" 
    from (select array_agg("Type"::text) as "Types" 
      from "B" 
      group by "UserId" 
     ) t 
; 

Chodzi o to, że najpierw używamy podzapytanie, które produkuje, dla każdego użytkownika, tablicę zawierającą jego/jej rodzaje; zapytanie zewnętrzne po prostu zlicza tablice zawierające każdy zestaw typów.

Możesz zobaczyć go w akcji pod numerem http://sqlfiddle.com/#!15/cbb45/1. (Wcześniej również ja tam zmodyfikowaną wersję podzapytania, które pomogą Ci zobaczyć, jak to działa.)

Some odpowiedniej dokumentacji PostreSQL:

+0

To jest bardzo ładne. Czy chcielibyśmy tutaj COUNT(), czy SUM()? –

+0

To zapytanie wykonuje dokładnie to, czego potrzebowałem. Dzięki za mil! –

+0

@AmilOsmanli: Nie ma za co! – ruakh

0

Może interpretuję to źle, ale myślę, że możesz zrobić całkiem proste stwierdzenie sprawy w swoim oświadczeniu wyboru, ale zamiast liczyć zrobić SUMA:

SELECT SUM(CASE b.Types WHEN 'A' THEN 1 ELSE 0) as COUNT_A, 
     SUM(CASE b.Types WHEN 'B' THEN 1 ELSE 0) as COUNT_B 
FROM A 
JOIN B 
ON A.id = B.user_id 
WHERE b1.type = 'A' or b2.type = 'B' 
Powiązane problemy