【问题标题】:Oracle - How to sum related items?Oracle - 如何汇总相关项目?
【发布时间】:2015-12-22 13:48:21
【问题描述】:

我有一组要报告的数据(在 Oracle 12c 中)。我想根据“ITEM”列的值显示某些分组的总和。如果 ITEM = ('A', 'B' 或 'C'),那么它们会被“组合”在一起,并将列 Cost1 和 Cost2 的值相加。这称为“组 1”。 Group2 包含项目('D,E,F')。只有 6 个分组,由大约 13 个静态/固定项目组成。我确切地知道每个分组中的项目。

这是一组示例数据,边框显示了应该组合在一起的内容。第二个清单显示了输出应该是什么样子。我想我想在一个案例陈述中总结,但我似乎无法理解它......

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    CASE 语句适用于这种一次性值转换:

    SELECT
      Year,
      CASE
        WHEN Item IN ('A', 'B', 'C') THEN 'Group1'
        WHEN Item IN ('D', 'E', 'F') THEN 'Group2'
        ELSE 'Others' END AS Item,
      SUM(Cost1),
      SUM(Cost2)
    FROM myTable
    GROUP BY
      Year,
      CASE
        WHEN Item IN ('A', 'B', 'C') THEN 'Group1'
        WHEN Item IN ('D', 'E', 'F') THEN 'Group2'
        ELSE 'Others' END;
    

    请注意,GROUP BY 表达式必须准确在列选择列表中声明,除非您必须删除别名 (AS Item)。

    【讨论】:

    • 为了防止null 总结(并得到null)你可能想要SUM(NVL(Cost1, 0)) 或类似的结构
    • 通常我会做类似的事情,但示例输出的结果为空,其中输入为空(第 15 年/第 1 组/第 1 年)。 Year 15/Group 2/Cost 1 没问题:Oracle 会将 3 相加并忽略 null,因此结果将为 3。
    【解决方案2】:

    看起来你想要Group By查询:

      select Year,
             case
               when item = 'A' or item = 'B' or item = 'C' then
                 'Group1' 
               else 
                 'Group2' 
             end as Item 
             Sum(nvl(Cost1, 0)) as Cost1, -- note NVL to prevent nulls from summing
             Sum(nvl(Cost2, 0) as Cost2
        from MyTable
    group by Year,
             Item
    

    【讨论】:

      【解决方案3】:

      如果不存储组的值,那么最简单的方法是使用 case 语句和聚合函数。您可以使用这些值创建一个 cte,以便于维护;或者可能是pipelined tablefunction

      Select year, case when item in ('A','B','C') then 'Group1'
                  when item in ('D','E','F' then 'GROUP2' else
                  'Unhandled' end as Item, Sum(Cost1) as cost1, Sum(Cost2) as cost2
      From TableName
      Group by year, case when item in ('A','B','C') then 'Group1'
                  when item in ('D','E','F' then 'GROUP2' else
                  'Unhandled' end 
      

      【讨论】:

        【解决方案4】:

        除了使用 CASE 进行映射之外,您还可以在专用表 myItem 中提取映射逻辑

          CREATE TABLE  myItem 
           ("ITEM" VARCHAR2(1), 
            "GROUP_ID" VARCHAR2(6), 
             PRIMARY KEY ("ITEM")
           );
        

        并加入此表以在 GROUPing 之前获取组

        with add_group as (
        select a.*, b.group_id from myTable a
        left outer join myItem b
        on a.item = b.item
        )
        select .... your GROUP BY query here
        

        这将使查询更加稳定,即使出现新的项目或组。

        【讨论】:

          猜你喜欢
          • 2021-08-20
          • 1970-01-01
          • 1970-01-01
          • 2010-11-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多