oracle SQL查询将行转换为具有附加计算列的列[已关闭]

kqlmhetl  于 2023-02-15  发布在  Oracle
关注(0)|答案(3)|浏览(119)
    • 已关闭**。此问题需要超过focused。当前不接受答案。
    • 想要改进此问题吗?**更新此问题,使其仅关注editing this post的一个问题。

3天前关闭。
此帖子已在2天前编辑并提交审核,无法重新打开帖子:
原始关闭原因未解决
Improve this question
示例数据如下所示:

DATE           Count   Code
02-JAN-2023    25       A
03-JAN-2023    10       A
05-JAN-2023    15       A
01-JAN-2023    5        B
02-JAN-2023    20       B
04-JAN-2023    6        B
05-JAN-2023    9        B

我需要将代码为"A"或"B"的行转换为A和B列,并创建另一列来计算A和B之间的差值(DIFF = A-B)。空值被视为0。结果应按日期分组和排序。
预期结果应为:

Date               A      B     DIFFERENCE(A-B)
01-JAN-2023               5       -5
02-JAN-2023        25    20        5
03-JAN-2023        10             10
04-JAN-2023               6       -6
05-JAN-2023        15     9        6
xfb7svmp

xfb7svmp1#

你需要一个条件聚合来得到想要的结果-

SELECT `date`, MAX(CASE WHEN CODE = 'A' THEN `count` ELSE NULL END) A,
       MAX(CASE WHEN CODE = 'B' THEN `count` ELSE NULL END) B,
       NVL(MAX(CASE WHEN CODE = 'A' THEN `count` ELSE NULL END), 0) - 
          NVL(MAX(CASE WHEN CODE = 'B' THEN `count` ELSE NULL END), 0) difference
  FROM your_table
 GROUP BY `date`;

Demo.

s3fp2yjn

s3fp2yjn2#

条件聚合,是的-但最有可能 * 不同 * 聚合(比Ankit建议的),我相信-sum而不是max。对于您发布的示例数据,这真的不重要,但可能有更多的行,甚至可能是同一日期,所以max不会返回正确的结果。
考虑在case表达式中使用else 0,而不是NVL函数(使用Ankit)。
此外,您不应该(也可能没有)使用保留字命名列;date是为数据类型保留的,所以要么列名不是数据类型,要么用双引号将列名括起来(这通常是个坏主意)。
尽管可以在同一条select语句中执行此操作,但使用子查询或CTE(如我的示例所示)是一个 * 更简洁 * 的选择;结果将是一样的,但这更容易阅读。
样本数据:

SQL> select * from test;

DATUM          COUNT CODE
--------- ---------- -----
02-JAN-23         25 A
03-JAN-23         10 A
05-JAN-23         15 A
01-JAN-23          5 B
02-JAN-23         20 B
04-JAN-23          6 B
05-JAN-23          9 B

7 rows selected.

质询:

SQL> with temp as
  2    (select datum,
  3       sum(case when code = 'A' then count else 0 end) as count_a,
  4       sum(case when code = 'B' then count else 0 end) as count_b
  5     from test
  6     group by datum
  7    )
  8  select datum, count_a, count_b,
  9    count_a - count_b as diff
 10  from temp
 11  order by datum;

DATUM        COUNT_A    COUNT_B       DIFF
--------- ---------- ---------- ----------
01-JAN-23          0          5         -5
02-JAN-23         25         20          5
03-JAN-23         10          0         10
04-JAN-23          0          6         -6
05-JAN-23         15          9          6

SQL>
rkkpypqq

rkkpypqq3#

您可以使用PIVOT获得预期结果:

Select  A_DATE, COL_A, COL_B, Nvl(COL_A, 0) - Nvl(COL_B, 0) "DIFF_A_B"
From      ( Select  A_DATE, CNT, CODE From  tbl )
            PIVOT   ( MAX(CNT) FOR CODE IN('A' "COL_A", 'B' "COL_B")    )
Order By A_DATE

...

WITH        -- Sample data
    tbl AS
        (
            Select To_Date('02-JAN-2023', 'dd-MON-yyyy') "A_DATE", 25 "CNT", 'A' "CODE" From Dual Union All
            Select To_Date('03-JAN-2023', 'dd-MON-yyyy') "A_DATE", 10 "CNT", 'A' "CODE" From Dual Union All
            Select To_Date('05-JAN-2023', 'dd-MON-yyyy') "A_DATE", 15 "CNT", 'A' "CODE" From Dual Union All
            Select To_Date('01-JAN-2023', 'dd-MON-yyyy') "A_DATE",  5 "CNT", 'B' "CODE" From Dual Union All
            Select To_Date('02-JAN-2023', 'dd-MON-yyyy') "A_DATE", 20 "CNT", 'B' "CODE" From Dual Union All
            Select To_Date('04-JAN-2023', 'dd-MON-yyyy') "A_DATE",  6 "CNT", 'B' "CODE" From Dual Union All
            Select To_Date('05-JAN-2023', 'dd-MON-yyyy') "A_DATE",  9 "CNT", 'B' "CODE" From Dual 
        )

R e s u l t :
A_DATE         COL_A      COL_B   DIFF_A_B
--------- ---------- ---------- ----------
01-JAN-23                     5         -5 
02-JAN-23         25         20          5 
03-JAN-23         10                    10 
04-JAN-23                     6         -6 
05-JAN-23         15          9          6

相关问题