集团由多个条件
鉴于表像集团由多个条件
| userid | active | anonymous |
| 1 | t | f |
| 2 | f | f |
| 3 | f | t |
我需要得到:
- 用户数
- 号与“主动” =真
- 的用户数量的用户'active'= false
- '匿名'= true的用户数
- “匿名”= false的用户数
单个查询。
至于现在,我只用工会解出来了:
SELECT count(*) FROM mytable
UNION ALL
SELECT count(*) FROM mytable where active
UNION ALL
SELECT count(*) FROM mytable where anonymous
所以我可以把第一号和找到简单的扣除非活动和非匿名用户。
有什么办法摆脱工会和计算的一些魔术和高效查询在PostgreSQL的9符合这些条件简单的记录是多少?
假设你列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服务器人员不习惯Postgres的正确boolean
类型,并倾向于走很长的路。
我知道你会得到一个更好的postgreSQL答案。我想我需要多学点这个数据库。 – Taryn 2013-04-23 13:47:53
@bluefeet:我尽我所能。 ;)仅仅学习主要的RDBMS版本也太多了。 – 2013-04-23 13:54:08
可以使用聚合函数与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;
我查看了执行计划并意识到,这个查询没有使用我在表上的任何索引,例如'在mytable((anonymous = true))'上创建索引table_anon''。所以它有'seq扫描'并且不使用任何过滤器。 – jdevelop 2013-04-23 01:12:47
您忘记提及您的表的NOT NULL约束,主键,数据类型和其他相关信息。还有PostgreSQL 9.? - [第一*和*版本号的第二部分与主要版本相关。](http://www.postgresql.org/support/versioning/) – 2013-04-23 01:49:15