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

How to get summary totals on unique IDs using analytics?

我的重复 table 有重复的 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

这是我的查询,也在 SQLFiddle

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

期望的结果:

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;

没有 elsecase 的默认值为 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: http://sqlfiddle.com/#!4/889a8/31/0

此答案基于您的示例 http://sqlfiddle.com/#!4/889a8/29,您可以通过获取 detail_book 和 detail_tree

的不同 ID 来避免重复 ID

请在此处查看结果http://sqlfiddle.com/#!4/889a8/44

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

除了分析函数,我可能会使用一种方法,首先 "flattening the table" (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'))
;

sql fiddle

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;

CASE 语句 returns NULL 当值不匹配时;这些不算。

Updated SQL Fiddle here. 顺便说一句,在您的查询中,您试图将 detail_book 匹配到 MAPL,而我认为您想要匹配 detail_tree,而我的查询反映了那。