Sql 如何使用分析获取唯一ID的汇总汇总?

Sql 如何使用分析获取唯一ID的汇总汇总?,sql,oracle,distinct,analytics,Sql,Oracle,Distinct,Analytics,我的重复表有重复的ID,但我需要唯一ID的摘要统计信息 Detail_id code book tree ----------- ------ ------ ------ 1 BR54 COOK PINE 1 BR55 COOK PINE 1 BR51 COOK PINE 2 BR55 COOK MAPL 2 BR60 COOK MA

我的重复表有重复的ID,但我需要唯一ID的摘要统计信息

 Detail_id   code   book   tree
----------- ------ ------ ------
  1          BR54   COOK   PINE
  1          BR55   COOK   PINE
  1          BR51   COOK   PINE
  2          BR55   COOK   MAPL
  2          BR60   COOK   MAPL
  3          BR61   FORD   PINE
  3          BR54   FORD   PINE
  3          BR55   FORD   PINE
这是我的问题,也是关于

预期结果:

COOK_TOTAL FORD_TOTAL PINE_TOTAL MAPL_TOTL
---------- ---------- ---------- ----------
  2          1          2         1

只需删除
else
子句,即可修改查询以获得所需内容:

select count(case detail_book when 'COOK' THEN 1 end) as cook_total,
       count(case detail_book when 'FORD' THEN 1 end) as ford_total,
       count(case detail_tree when 'PINE' THEN 1 end) as pine_total,
       count(case detail_book when 'MAPL' THEN 1 end) as mapl_total
from detail_records;
没有
else
case
的默认值为
NULL
,因此
count()
有效。就个人而言,对于这种类型的聚合,我更喜欢
sum()

select sum(case when detail_book = 'COOK' THEN 1 else 0 end) as cook_total,
       sum(case when detail_book = 'FORD' THEN 1 else 0 end) as ford_total,
       sum(case when detail_tree = 'PINE' THEN 1 else 0 end) as pine_total,
       sum(case when detail_book = 'MAPL' THEN 1 else 0 end) as mapl_total
from detail_records;

您可以使用分析函数和内联视图来避免重复计数问题:

select sum(case when detail_book = 'COOK' and book_cntr = 1 then 1 else 0 end) as cook_total,
       sum(case when detail_book = 'FORD' and book_cntr = 1 then 1 else 0 end) as ford_total,
       sum(case when detail_tree = 'PINE' and tree_cntr = 1 then 1 else 0 end) as pine_total,
       sum(case when detail_tree = 'MAPL' and tree_cntr = 1 then 1 else 0 end) as mapl_total
  from (select d.*,
               row_number() over(partition by detail_book, detail_id order by detail_book, detail_id) as book_cntr,
               row_number() over(partition by detail_tree, detail_id order by detail_tree, detail_id) as tree_cntr
          from detail_records d) v

Fiddle:

此答案基于您的示例,您可以使用该示例通过获取详细信息簿和详细信息树的不同ID来避免重复ID

请在这里检查结果


除了分析函数,我可能会使用一种方法,首先“展平表”(
union all
),然后旋转结果:

select *
  from (
    select   detail_book i
    from     detail_records
    group by detail_id, detail_book
  union all
    select   detail_tree
    from     detail_records
    group by detail_id, detail_tree
)
  pivot(count(i) for i in ('COOK', 'FORD', 'PINE', 'MAPL'))
;

我认为这里不需要分析函数:

SELECT COUNT(DISTINCT CASE WHEN detail_book = 'COOK' THEN detail_id END) AS cook_total
     , COUNT(DISTINCT CASE WHEN detail_book = 'FORD' THEN detail_id END) AS ford_total
     , COUNT(DISTINCT CASE WHEN detail_tree = 'PINE' THEN detail_id END) AS pine_total
     , COUNT(DISTINCT CASE WHEN detail_tree = 'MAPL' THEN detail_id END) AS mapl_total
  FROM detail_records;
当值不匹配时,
CASE
语句返回NULL;这些不算在内


顺便说一句,在您的查询中,您试图将
detail\u book
匹配到
MAPL
,而我认为您想要匹配
detail\u tree
,我的查询反映了这一点。

似乎这不是用户想要得到的(尽管这是我最初的解释)。我相信他是在为每个条件计算不同的
detail\u id
值,而不是计算每个条件发生的行。是的,贾斯汀,这是正确的。此线程()中的Fiddle#29生成正确的COOK#u总数。我想将类似的查询捕获到一个查询中。在我的答案中使用了detail\u id。。您可以检查它是否适用于you@zundarz . . . 然后将
detail\u id
添加到
select
groupbydetail\u id
select *
  from (
    select   detail_book i
    from     detail_records
    group by detail_id, detail_book
  union all
    select   detail_tree
    from     detail_records
    group by detail_id, detail_tree
)
  pivot(count(i) for i in ('COOK', 'FORD', 'PINE', 'MAPL'))
;
select *
from (
select decode(detail_book,'FORD','FORD_TOTAL','COOK','COOK_TOTAL','MAPL','MAPL_TOTAL','PINE','PINE_TOTAL','OTHER') i, 
    count(distinct detail_id) j
from detail_records
group by detail_book
union all
select DECODE(detail_tree,'FORD','FORD_TOTAL','COOK','COOK_TOTAL','MAPL','MAPL_TOTAL','PINE','PINE_TOTAL','OTHER') i, 
    count(distinct detail_id) j
from detail_records
group by detail_tree
)
  pivot(sum(j) for i in ('COOK_TOTAL', 'FORD_TOTAL', 'PINE_TOTAL', 'MAPL_TOTAL','OTHER'))
;
SELECT COUNT(DISTINCT CASE WHEN detail_book = 'COOK' THEN detail_id END) AS cook_total
     , COUNT(DISTINCT CASE WHEN detail_book = 'FORD' THEN detail_id END) AS ford_total
     , COUNT(DISTINCT CASE WHEN detail_tree = 'PINE' THEN detail_id END) AS pine_total
     , COUNT(DISTINCT CASE WHEN detail_tree = 'MAPL' THEN detail_id END) AS mapl_total
  FROM detail_records;