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

问题描述:

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

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

以下是测试的示例创建代码。

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在第一行 和只有与标志B = 1,以便计数是1在第二行 的Cat3计数为0,因为没有排与标志= 1

+0

您列出几乎所有的数据库在那里;你实际使用哪一个? –

+0

它为甲骨文,添加其他人,因为它可能与其他人类似。 – Thunder

+1

不,你接受的答案不会在MySQL上运行,也不会在SQL Server上运行,因为它没有'DECODE()'函数。将来,只需标记您的实际数据库。 –

使用count(distinct decode(flag,1,person,null))

,而忽略人,其中标志不等于 “1”,将工作得更快

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

或者你可以使用分析功能Over (partition by)子句

一般分析函数工作得更快。下面是例子如何应用解析函数的这个问题:

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

旁观的执行计划,选择什么更好的为您

+0

'并且会更快地工作......我怀疑这是否会比'WHERE'子句更快,如果'Flag'列被索引。 –

+0

可能是,我们可以在执行计划中看到它 –

+0

令人惊异的解决方案,第一种解决方案对我来说似乎更加清楚谢谢!我认为第二种解决方案中的独特关键字使其效率低于第一种解决方案。 – Thunder

使用COUNT(DISTINCT PERSON)

SELECT Category, 
     COUNT(DISTINCT CASE WHEN Flag = 1 THEN PERSON END) AS distinct_count 
FROM MYGROUP 
GROUP BY Category 

演示在这里:

SQLFiddle