Sql 如何基于另一列的值获取列的不同计数

Sql 如何基于另一列的值获取列的不同计数,sql,oracle,group-by,Sql,Oracle,Group By,如何根据另一列的值获取列的不同计数 我可以理解,这可以通过创建另一个中间表来实现,但我正在对具有数十亿行的表运行此查询,因此,如果我们可以在一个查询中得到结果,而不是创建另一个分组,那会更好 下面是测试的示例创建代码 CREATE TABLE MYGROUP ( Category,PERSON,Flag ) AS SELECT 'Cat1','A','1' FROM DUAL UNION ALL SELECT 'Cat1','A','0' FROM DUAL UNION AL

如何根据另一列的值获取列的不同计数

我可以理解,这可以通过创建另一个中间表来实现,但我正在对具有数十亿行的表运行此查询,因此,如果我们可以在一个查询中得到结果,而不是创建另一个分组,那会更好

下面是测试的示例创建代码

CREATE TABLE MYGROUP ( Category,PERSON,Flag ) AS
          SELECT 'Cat1','A','1' FROM DUAL
UNION ALL SELECT 'Cat1','A','0' FROM DUAL
UNION ALL SELECT 'Cat1','A','1' FROM DUAL
UNION ALL SELECT 'Cat1','B','1' FROM DUAL
UNION ALL SELECT 'Cat1','B','0' FROM DUAL
UNION ALL SELECT 'Cat2','A','0' FROM DUAL
UNION ALL SELECT 'Cat2','A','0' FROM DUAL
UNION ALL SELECT 'Cat2','A','0' FROM DUAL
UNION ALL SELECT 'Cat2','B','1' FROM DUAL
UNION ALL SELECT 'Cat2','B','1' FROM DUAL
UNION ALL SELECT 'Cat2','B','0' FROM DUAL
UNION ALL SELECT 'Cat3','X','0' FROM DUAL
UNION ALL SELECT 'Cat3','Y','0' FROM DUAL;
期望输出:

Category    Count of Distinct Persons with Flag =1
Cat1        2
Cat2        1
Cat3        0
产出原因 A和B都有标志=1,所以第一行的计数是2 并且只有标志=1的B,所以第二行的计数是1 Cat3计数为0,因为没有带Flag=1的行

使用
计数(不同的人)

此处演示:

使用
计数(不同解码(标志,1,个人,空))

它将忽略标志不等于“1”的人员,并将更快地工作

select  category ,count (distinct decode(flag,1,person,null)) countof from MYGROUP
group by category
或者您可以使用分析函数
Over(partitionby)
子句

一般来说,分析函数工作得更快。下面是如何将分析函数应用于此问题的示例:

select distinct  category ,count (distinct decode(flag,1,person,null)) over (partition by category) countof from MYGROUP

查看执行计划,选择对您更有利的

并将更快地工作
。。。如果将
标志
列编入索引,我怀疑这会比
WHERE
子句快。可能是,我们可以在执行计划上看到它惊人的解决方案,第一个解决方案对我来说似乎更清晰谢谢!,我认为第二个解决方案中的不同关键字会使它比第一个解决方案效率低一些。是的,在第二个解决方案中有两个不同的表达式,但在某些情况下,它可能比第一个更快,因为analityc函数比简单的分组工作得快。您列出了几乎所有的数据库;您实际使用的是哪一个?它用于oracle,添加了其他,因为它可能与其他类似。不,您接受的答案根本不会在MySQL上运行,也不会在SQL Server上运行,因为它没有
DECODE()
函数。将来,只需标记实际数据库即可。
select distinct  category ,count (distinct decode(flag,1,person,null)) over (partition by category) countof from MYGROUP