【问题标题】:How to get summary totals on unique IDs using analytics?如何使用分析获取唯一 ID 的汇总总数?
【发布时间】:2015-03-29 12:10:58
【问题描述】:

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

【问题讨论】:

    标签: sql oracle distinct analytics


    【解决方案1】:

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

    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

    【讨论】:

      【解决方案2】:

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

      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_tree 时,您尝试将 detail_book 匹配到 MAPL,而我的查询反映了这一点。

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          【解决方案4】:

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

          【讨论】:

          • 看来这不是用户想要达到的目的(尽管这是我最初的解释)。我相信他正在尝试计算每个条件的不同 detail_id 值,而不是尝试计算每个条件发生的行。
          • 是的,贾斯汀说的没错。此线程中的小提琴 #29 (sqlfiddle.com/#!4/889a8/29) 为 COOK_TOTAL 生成正确的数字。我想将类似的查询捕获到一个查询中。
          • 在我的回答中使用了 detail_id .. 你可以检查它是否适合你
          • @zundarz 。 . .然后你可以将detail_id 添加到selectgroup by detail_id
          【解决方案5】:

          除了分析函数之外,我可能会使用一种方法,首先“展平表格”(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

          【讨论】:

            【解决方案6】:
            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'))
            ;
            

            【讨论】:

              猜你喜欢
              • 2021-04-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多