2013-06-12 13 views
12

Z dwóch kolumn w mojej tabeli chcę uzyskać ujednoliconą liczbę dla wartości w tych kolumnach. Jako przykład, dwie kolumny:PostgreSQL Wielokrotne liczenia dla jednej tabeli

Tabela: raporty

| type  | place | 
----------------------------------------- 
| one   | home | 
| two   | school | 
| three  | work | 
| four  | cafe | 
| five  | friends | 
| six   | mall | 
| one   | work | 
| one   | work | 
| three  | work | 
| two   | cafe | 
| five  | cafe | 
| one   | home | 

Jeśli zrobić: typu SELECT count (*) z raportów grupy według rodzaju

uzyskać:

| type  | count | 
----------------------------- 
| one   | 4  | 
| two   | 2  | 
| three  | 2  | 
| four  | 1  | 
| five  | 2  | 
| six   | 1  | 

Próbuję uzyskać coś takiego: (jedna kolumna po prawej z moimi typami zgrupowanymi razem i wiele kolumn z h dolin liczyć na każdym miejscu) uzyskać:

| type  | home | school | work | cafe | friends | mall | 
----------------------------------------------------------------------------------------- 
| one   | 2  |   | 2  |   |   |   | 
| two   |   | 1  |   | 1  |   |   | 
| three  |   |   | 2  |   |   |   | 
| four  |   |   |   | 1  |   |   | 
| five  |   |   |   | 1  | 1  |   | 
| six   |   |   |   |   |   | 1  | 

co byłoby wynikiem uruchomiony licznik jak ten powyżej na każdym miejscu takim jak to:

SELECT type, count(*) from reports where place = 'home' 
group by type 
SELECT type, count(*) from reports where place = 'school' 
group by type 
SELECT type, count(*) from reports where place = 'work' 
group by type 
SELECT type, count(*) from reports where place = 'cafe' 
group by type 
SELECT type, count(*) from reports where place = 'friends' 
group by type 
SELECT type, count(*) from reports where place = 'mall' 
group by type 

Czy to możliwe z PostgreSQL ?

Z góry dziękuję.

+0

Tutaj mamy jakieś ostateczne prawo odnośnika. Np. ("dom", "szkoła" ...) Mam wyszukiwanie situtation może wiedzieć tylko w czasie wykonywania. dowolny szablon sql dla tego? – Pyare

Odpowiedz

29

można użyć case w tym przypadku -

SELECT type, 
     sum(case when place = 'home' then 1 else 0 end) as Home, 
     sum(case when place = 'school' then 1 else 0 end) as school, 
     sum(case when place = 'work' then 1 else 0 end) as work, 
     sum(case when place = 'cafe' then 1 else 0 end) as cafe, 
     sum(case when place = 'friends' then 1 else 0 end) as friends, 
     sum(case when place = 'mall' then 1 else 0 end) as mall 
    from reports 
group by type 

To powinno rozwiązać problem

@ST Mohammeda, Aby uzyskać tego typu możemy po prostu użyć using po group lub where warunku w zapytaniu zewnętrznym , poniżej -

select type, Home, school, work, cafe, friends, mall from (
SELECT type, 
     sum(case when place = 'home' then 1 else 0 end) as Home, 
     sum(case when place = 'school' then 1 else 0 end) as school, 
     sum(case when place = 'work' then 1 else 0 end) as work, 
     sum(case when place = 'cafe' then 1 else 0 end) as cafe, 
     sum(case when place = 'friends' then 1 else 0 end) as friends, 
     sum(case when place = 'mall' then 1 else 0 end) as mall 
    from reports 
group by type 
) 
where home >0 and School >0 and Work >0 and cafe>0 and friends>0 and mall>0 
+1

Aby uzyskać puste (zerowe) kolumny zamiast zera, należy zawijać sumy w wywołaniach 'nullif'. Użycie 'count' z' null' zamiast '0' (przez całkowite pominięcie' ELSE 0') dla nieudanego przypadku działa również bez problemu, nie musisz zmieniać na 'sum'. –

+0

Dzięki za odpowiedzi, pomogli mi rozwiązać mój problem. – Chuydb

+0

Ostatni przecinek w instrukcji sql (tuż przed słowem kluczowym "od") powoduje błąd. – mosid

12

Odpowiedz przez praktik garg is co ego właściwego, nie jest konieczne stosowanie else 0:

SELECT type, 
     sum(case when place = 'home' then 1 end) as home, 
     sum(case when place = 'school' then 1 end) as school, 
     sum(case when place = 'work' then 1 end) as work, 
     sum(case when place = 'cafe' then 1 end) as cafe, 
     sum(case when place = 'friends' then 1 end) as friends, 
     sum(case when place = 'mall' then 1 end) as mall, 
from reports 
group by type 

Można także skorzystać z następującej nawet krótszą składnię:

SELECT type, 
     sum((place = 'home')::int) as home, 
     sum((place = 'school')::int) as school, 
     sum((place = 'work')::int) as work, 
     sum((place = 'cafe')::int) as cafe, 
     sum((place = 'friends')::int) as friends, 
     sum((place = 'mall')::int) as mall, 
from reports 
group by type 

to będzie działać, ponieważ wartość logiczna true lanego na 1, gdy warunek jest spełniony.

2

Można użyć klauzuli filtru, a także:

SELECT 
    type, 
    sum(1) FILTER (WHERE place = 'home') AS home, 
    sum(1) FILTER (WHERE place = 'school') AS school, 
    sum(1) FILTER (WHERE place = 'work') AS work, 
    sum(1) FILTER (WHERE place = 'cafe') AS cafe, 
    sum(1) FILTER (WHERE place = 'friends') AS friends, 
    sum(1) FILTER (WHERE place = 'mall') AS mall 
FROM 
    reports 
GROUP BY 
    type