Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 按多个标准分组_Sql_Postgresql_Aggregate Functions - Fatal编程技术网

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的用户数
使用单个查询

到目前为止,我只使用了union提出了解决方案:

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版本就有太多的知识。