Sql 按多个标准分组
考虑到这张桌子Sql 按多个标准分组,sql,postgresql,aggregate-functions,Sql,Postgresql,Aggregate Functions,考虑到这张桌子 | userid | active | anonymous | | 1 | t | f | | 2 | f | f | | 3 | f | t | 我需要得到: 用户数 “活动”的用户数=真 “活动”的用户数=false “匿名”为true的用户数 “匿名”为false的用户数 使用单个查询 到目前为止,我只使用了union提出了解决方案: SELECT count(
| userid | active | anonymous |
| 1 | t | f |
| 2 | f | f |
| 3 | f | t |
我需要得到:
- 用户数
- “活动”的用户数=真
- “活动”的用户数=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中,有没有办法通过一些神奇而高效的查询来摆脱union并计算与这些简单条件相匹配的记录数?您可以使用带有
大小写的聚合函数来在单独的列中获得结果:
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;
请参见您可以将聚合函数与
大小写一起使用,以在单独的列中获得结果:
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;
请参见假设您的列为
布尔非空
,这应该会快一点:
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;
请详细解释此密切相关答案中使用的技巧:索引几乎没有任何用处,因为无论如何都必须读取整个表。如果您的行比示例中的行大,则覆盖索引可能会有所帮助。取决于实际表格的具体情况 ->对每个值进行比较
SQL server人员不习惯使用正确的
布尔型Postgre类型,并且倾向于走很长的路。假设您的列是布尔型非空的
,这应该会快一点:
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;
请详细解释此密切相关答案中使用的技巧:
索引几乎没有任何用处,因为无论如何都必须读取整个表。如果您的行比示例中的行大,则覆盖索引可能会有所帮助。取决于实际表格的具体情况
->对每个值进行比较
SQL server人员不习惯使用正确的布尔型Postgre类型,并且倾向于走很长的路。我查看了执行计划并意识到,此查询不使用我在表上的任何索引,例如“在mytable上创建索引表((anonymous=true))”。所以它有“seq scan”并且不使用任何过滤器。我查看了执行计划,发现这个查询没有使用我在表上的任何索引,例如“在mytable上创建索引表((anonymous=true))”。因此,它具有“seq scan”,并且不使用任何筛选器。您忘记了提及NOT NULL
约束、主键、数据类型以及有关表的其他相关信息。也是PostgreSQL 9.?-您忘了提及notnull
约束、主键、数据类型和表的其他相关信息。也是PostgreSQL 9.?-我知道你会得到一个更好的postgreSQL答案。我想我需要多学一点这个数据库。@bluefeet:我尽我所能。;)单凭主要的RDBMS版本就有太多的知识需要学习。我知道你会得到一个更好的postgreSQL答案。我想我需要多学一点这个数据库。@bluefeet:我尽我所能。;)仅仅使用主要的RDBMS版本就有太多的知识。