Oracle SQL 行到具有分组依据和总和的列

Posted

技术标签:

【中文标题】Oracle SQL 行到具有分组依据和总和的列【英文标题】:Oracle SQL rows to column with group by and sum 【发布时间】:2021-01-31 09:30:20 【问题描述】:

我有一个包含以下数据的表格。

ID    Name     DiscountGroup Discount DicountCategory
A     XXX      G025          25        MANGMNT
A     XXX      T005           5        HIGH GPA
A     XXX      T010          10        
B     XXXB     G040          40        SOMETXT
B     XXXB     T005           5        HIGH GPA

我想将数据显示为

ID    Name     PermanentDiscount Cateogry TempDiscount 
A     XXX      25                MANGMNT  15
B     XXXB     40                SOMETXT   5

即 1 行中的永久和临时折扣。所有永久折扣均以 GXXX 开头,后跟 3 位数。同样,所有临时折扣都以 TXXX 开头,后跟 3 位数字,其中 XXX 表示实际折扣。一个ID可以有多个临时折扣,但只能有一个永久折扣。我尝试使用

SELECT *
  FROM tableA
PIVOT (
  MAX(Discount) FOR DiscountGroup IN ('')
);

但我无法找出列表中的值。

【问题讨论】:

您可以check out 获取动态旋转选项。 【参考方案1】:

您可以为每个 ID/姓名添加一个包含临时折扣总和的列,然后过滤具有永久折扣的行。

select ID, Name, PermanentDiscount, Cateogry, TempDiscount
from (
    select
        DiscountGroup, ID, Name,
        Discount as PermanentDiscount,
        DicountCategory as Cateogry,
        sum(case when DiscountGroup like 'T%' then Discount else 0 end) over(partition by ID, Name) as TempDiscount
    from table
)
where DiscountGroup like 'G%'
order by ID, Name;

【讨论】:

【参考方案2】:

这应该可行:

WITH sample_data AS 
   ( SELECT 'A' AS id, 'XXX' AS name, 'G025' AS DiscountGroup, 25 AS Discount, 'MANGMNT' AS DiscountCategory FROM DUAL UNION ALL
     SELECT 'A' AS id, 'XXX' AS name, 'T005' AS DiscountGroup, 5 AS Discount, 'HIGH GPA' AS DiscountCategory FROM DUAL UNION ALL
     SELECT 'A' AS id, 'XXX' AS name, 'T010' AS DiscountGroup, 10 AS Discount, NULL AS DiscountCategory FROM DUAL UNION ALL
     SELECT 'B' AS id, 'XXXB' AS name, 'G040' AS DiscountGroup, 40 AS Discount, 'SOMETXT' AS DiscountCategory FROM DUAL UNION ALL
     SELECT 'B' AS id, 'XXXB' AS name, 'T005' AS DiscountGroup, 5 AS Discount, 'HIGH GPA' AS DiscountCategory FROM DUAL
   )
SELECT id,
       name,
       MAX(CASE WHEN DiscountGroup = 'G' THEN Discount ELSE 0 END) AS PermanentDiscount,
       MAX(CASE WHEN DiscountGroup = 'G' THEN Cateogry ELSE NULL END) AS Cateogry,
       SUM(CASE WHEN DiscountGroup = 'T' THEN Discount ELSE 0 END) AS TempDiscount
  FROM ( SELECT id,
                name,
                SUBSTR(DiscountGroup, 1, 1) AS DiscountGroup,
                Discount,
                FIRST_VALUE(DiscountCategory) OVER(PARTITION BY id, name, SUBSTR(DiscountGroup, 1, 1) ORDER BY Discount DESC) AS Cateogry
           FROM sample_data
       )
  GROUP BY id, name
  ORDER BY id, name;

结果:

I NAME PERMANENTDISCOUNT CATEOGRY TEMPDISCOUNT
- ---- ----------------- -------- ------------
A XXX                 25 MANGMNT            15
B XXXB                40 SOMETXT             5

【讨论】:

【参考方案3】:

我认为它应该适合你 =>

WITH CTE AS(
SELECT ID,SUM(Discount) TempDiscount
FROM tableA 
WHERE DiscountGroup LIKE 'T%' 
GROUP BY ID )
SELECT a.*,c.TempDiscount FROM
CTE c
INNER JOIN tableA a ON a.ID=c.ID AND a.DiscountGroup LIKE 'G%'

注意:你可以在这里查看我的代码 => LINK

【讨论】:

【参考方案4】:

我在雪花中运行这个。

select id
      ,max(Name)
      ,sum(case when discountgroup like 'G%' then discount else 0 end) Permanentdiscount
      ,max(case when discountgroup like 'G%' then discountcategory end ) category
      ,sum(case when discountgroup like 'T%' then discount else 0 end) Temporarydiscount
from SAMPLE_DATA
      group by id;

【讨论】:

以上是关于Oracle SQL 行到具有分组依据和总和的列的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 数据透视 + 总和 + 分组依据

在同一分组中添加具有上述所有行总和的列

加入和分组依据 - 选择列表中的列无效

SQL 语法问题 - 分组依据 - Oracle

oracle12c,sql,分组依据

不同的总和和分组依据