选择具有不同条件的多个列

时间:2016-08-03 06:37:56

标签: sql postgresql select count

包含以下字段的用户表。

id
agent_id
locality
total
building_type
price

我通过以下查询得到不同的统计结果

SELECT agent_id, COUNT(*) AS stat_1 
FROM users 
WHERE "building_type" = 'single' 
AND ("price" BETWEEN 0 AND 200000) 
GROUP BY "agent_id" 
order by agent_id

SELECT agent_id, COUNT(*) AS stat_2 
FROM users 
WHERE "building_type" = 'single' 
AND ("price" BETWEEN 200001 AND 350000) 
GROUP BY "agent_id" 
order by agent_id

SELECT agent_id, COUNT(*) AS stat_3 
FROM users 
WHERE "building_type" = 'single' 
AND ("price" BETWEEN 3500001 AND 500000) 
GROUP BY "agent_id" 
order by agent_id

但我希望得到所有统计数据(如

)的相同查询结果
SELECT agent_id, 
       COUNT(*) AS stat_1, 
       COUNT(*) AS stat_2, 
       COUNT(*) AS stat_3 
from users 
where <Conditions>

如何在一个查询中获得此结果?

2 个答案:

答案 0 :(得分:4)

Postgres 9.4通过添加允许您对聚合函数应用条件的filter子句,以优雅的方式解决了这些问题:

SELECT   agent_id, 
         COUNT(*) FILTER (WHERE "price" BETWEEN 0 AND 200000) AS stat_1,
         COUNT(*) FILTER (WHERE "price" BETWEEN 200001 AND 350000) AS stat_2,
         COUNT(*) FILTER (WHERE "price" BETWEEN 3500001 AND 500000) AS stat_3
FROM     users 
WHERE    "building_type" = 'single' 
GROUP BY "agent_id" 
ORDER BY "agent_id"

对于不允许filter子句的早期版本,您可以通过将聚合函数应用于case表达式来自己实现相同的行为。在这里,我们利用count的属性忽略null s:

SELECT   agent_id, 
         COUNT(CASE WHEN "price" BETWEEN 0 AND 200000 THEN 1 END) AS stat_1,
         COUNT(CASE WHEN "price" BETWEEN 200001 AND 350000 THEN 1 END) AS stat_2,
         COUNT(CASE WHEN "price" BETWEEN 3500001 AND 500000 THEN 1 END) AS stat_3
FROM     users 
WHERE    "building_type" = 'single' 
GROUP BY "agent_id" 
ORDER BY "agent_id"

答案 1 :(得分:3)

您可以使用条件聚合:

SELECT agent_id, 
       COUNT(*) filter (where price BETWEEN 0 AND 200000) as stat_1,
       COUNT(*) filter (where price BETWEEN 200001 AND 350000)  AS stat_2, 
       COUNT(*) filter (where price BETWEEN 3500001 AND 500000)  AS stat_3 
from users 
WHERE building_type = 'single' 
GROUP BY agent_id
order by agent_id