给出像
这样的表格| userid | active | anonymous |
| 1 | t | f |
| 2 | f | f |
| 3 | f | t |
我需要得到:
单一查询。
就目前而言,我只使用 union :
推出解决方案SELECT count(*) FROM mytable
UNION ALL
SELECT count(*) FROM mytable where active
UNION ALL
SELECT count(*) FROM mytable where anonymous
所以我可以使用第一个号码,并通过简单的扣除找到非活跃和非匿名用户。
有没有办法摆脱联合并计算符合这些简单条件的记录数量以及 PostgreSQL 9 中的魔术和高效查询?
答案 0 :(得分:3)
您可以使用带CASE
的聚合函数将结果放在单独的列中:
select
count(*) TotalUsers,
sum(case when active = 't' then 1 else 0 end) TotalActiveTrue,
sum(case when active = 'f' then 1 else 0 end) TotalActiveFalse,
sum(case when anonymous = 't' then 1 else 0 end) TotalAnonTrue,
sum(case when anonymous = 'f' then 1 else 0 end) TotalAnonFalse
from mytable;
答案 1 :(得分:2)
假设您的列为boolean NOT NULL
,这应该会更快一些:
SELECT total_ct
,active_ct
,(total_ct - active_ct) AS not_active_ct
,anon_ct
,(total_ct - anon_ct) AS not_anon_ct
FROM (
SELECT count(*) AS total_ct
,count(active OR NULL) AS active_ct
,count(anonymous OR NULL) AS anon_ct
FROM tbl
) sub;
详细解释这个密切相关答案中使用的技巧:
Compute percents from SUM() in the same SELECT sql query
索引几乎没有任何用处,因为无论如何都必须读取整个表格。如果您的行大于示例中的行,则覆盖索引可能会有所帮助。取决于您的实际表格的具体情况。
- > SQLfiddle与每个值的@bluefeet's version with CASE
statements进行比较。
SQL服务器用户不习惯boolean
类型的Postgres,并且往往会走很长的路。