2012-02-11 4 views
0

Я запускаю PostgreSQL. У меня есть таблица под названием foo содержание .Its являются:Пользовательская группа По postgresql

city|number 
'oo'|12 
'ss'|11 
'ss'|23 
'oo'|11 
'pp'|21 

Если я выполнить запрос как select count(city) from foo group by city having number<21 я получить

city|number 
'oo'|2 
'ss'|2 

, но я хочу, чтобы результат рассмотреть все возможные случаи city, как это :

city|number 
'oo'|2 
'ss'|2 
'pp'|0 

Как должен выглядеть запрос?

+0

Что вы подразумеваете под словом «рассмотрите все возможные случаи»? 21 не '' '' 21, поэтому 'pp' не появится. – fnl

+0

Да, но это требование должно также рассмотреть pp. – goblin2986

+0

Тогда почему бы просто не использовать 'HAVING number <= 21'? – fnl

ответ

0

Это может быть решена с помощью соединения слева:

select f1.city, count(f2.number) as total from foo as f1 
left join foo as f2 
on f1.cityId = f2.cityId and f1.number < 21 
group by f1.city 

Вот рабочая example

PS: Ваш пример является неправильным, потому что сс должны иметь значение 1, а не 2:

YOUR EXAMPLE   WHAT I THINK YOU REALLY WANT 
city|number     city|number 
'oo'|2      'oo'|2 
'ss'|2      'ss'|1 
'pp'|0      'pp'|0 

Надеюсь, это поможет.

1
SELECT city, count(NULLIF(number < 21, false)) FROM cities GROUP BY city 

должен дать вам желаемый результат.

0

Думает, что я неправильно вопрос первый раз, но попробуйте это:

select f1.city,count(*) from foo f1 
where f1.city in (select f2.city from foo f2 where f2.number < 21) 
group by f1.city 
union 
select f3.city,0 from foo f3 
where not exists (select * from foo f4 where f3.city=f4.city and f4.number < 21) 
group by f3.city 

Союз разделяет запрос таким образом, что первая половина будет определить, какие города есть запись < 21, а затем подсчитать количество вхождений из этих городов.

Вторая половина идентифицирует города, у которых нет записи < 21, а затем подсчитывает их.