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

时间:2015-01-30 03:27:57

标签: 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   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

6 个答案:

答案 0 :(得分:4)

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

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

小提琴: http://sqlfiddle.com/#!4/889a8/31/0

答案 1 :(得分:3)

我认为你不需要解析功能:

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;那些都不算数。

Updated SQL Fiddle here.顺便说一句,在您的查询中,当我认为您要匹配detail_book时,您尝试将MAPLdetail_tree匹配,而我的查询则反映了这一点。

答案 2 :(得分:1)

此答案基于您的示例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);

答案 3 :(得分:0)

您可以通过删除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;

没有case的{​​{1}}的默认设置为else,因此NULL有效。就个人而言,我更喜欢count()这种类型的聚合:

sum()

答案 4 :(得分:0)

除了分析功能之外,我可能首先使用一种方法,然后将表格展平。 (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

答案 5 :(得分:0)

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'))
;