Oracle 查询 - 将列值显示为按日期范围求和的列名称

问题描述 投票:0回答:1

我需要编写一个预言机查询来查找 2 个给定日期之间每周(周一到周日)订购的总合同数量(例如,:startdate = '28-Nov-23' 和 :enddate = '15-Dec) -23') 并将日期值显示为列名称。

TABLE A:
CONTRACTNO  QTY SUPPLIER    CDATE
----------  --- --------    -----
23231       12  LG          28-Nov-23
23232       2   SM          23-Nov-23
23233       44  AP          11-Dec-23
23234       9   BR          25-Dec-23
23235       22  SM          15-Dec-23
23236       7   AP          08-Dec-23
23237       1   LG          30-Nov-23

预期输出:

Wk_27-Nov-23 Wk_04-Dec-23 Wk_11-Dec-23
-----------  -----------  -----------
13           7            66

其中 Wk_27-Nov-23 = Sum(Qty),从 2023 年 11 月 27 日到 12 月 3 日,下周从 23 年 12 月 4 日到 12 月 10 日,依此类推,直到 :enddate 之前的星期一.

我不知道从哪里开始,因为我对 Oracle SQL 还很陌生。到目前为止,我已使用以下查询将开始日期和结束日期之间的星期一插入到临时表中,但需要知道如何将其应用于 SUM()/GROUP。

select MonDate from (select (sysdate-7 + rownum -1) MonDate
from all_objects 
where rownum <= (to_date('15-DEC-23', 'dd-mon-yy')) - (sysdate-7))
where rtrim(to_char(MonDate, 'DAY')) = 'MONDAY';

谢谢!

oracle oracle11g
1个回答
0
投票

我需要编写一个 oracle 查询来查找 2 个给定日期之间每周(周一到周日)订购的总合同数量(例如:startdate = '28-Nov-23' 和 :enddate = '15-Dec-23')并将日期值显示为列名称。

使用条件聚合:

SELECT SUM(
         CASE
         WHEN cdate >= DATE '2023-11-27' AND cdate < DATE '2023-12-04'
         THEN qty
         END
       ) AS "Wk_27-Nov-23",
       SUM(
         CASE
         WHEN cdate >= DATE '2023-12-04' AND cdate < DATE '2023-12-11'
         THEN qty
         END
       ) AS "Wk_04-Dec-23",
       SUM(
         CASE
         WHEN cdate >= DATE '2023-12-11' AND cdate < DATE '2023-12-18'
         THEN qty
         END
       ) AS "Wk_11-Dec-23"
FROM   table_a;

对于样本数据:

CREATE TABLE TABLE_A (CONTRACTNO, QTY, SUPPLIER, CDATE) AS
SELECT 23231, 12, 'LG', DATE '2023-11-28' FROM DUAL UNION ALL
SELECT 23232,  2, 'SM', DATE '2023-11-23' FROM DUAL UNION ALL
SELECT 23233, 44, 'AP', DATE '2023-12-11' FROM DUAL UNION ALL
SELECT 23234,  9, 'BR', DATE '2023-12-25' FROM DUAL UNION ALL
SELECT 23235, 22, 'SM', DATE '2023-12-15' FROM DUAL UNION ALL
SELECT 23236,  7, 'AP', DATE '2023-12-08' FROM DUAL UNION ALL
SELECT 23237,  1, 'LG', DATE '2023-11-30' FROM DUAL;

输出:

23 年 11 月 27 周 12 月 23 日第 4 周 12 月 23 日第 11 周
13 7 66

在 SQL(不仅仅是 Oracle)中,语句必须具有已知的固定数量的列,并且您无法在查询中动态生成这些列的别名。因此,如果您不想将日期硬编码到别名中,那么静态查询是不可能的。

如果您确实想要动态列,那么您应该考虑将输出生成为行:

SELECT TRUNC(cdate, 'IW') AS week_start,
       SUM(qty) AS total_qty
FROM   table_a
WHERE  cdate >= DATE '2023-11-27'
AND    cdate <  DATE '2023-12-25'
GROUP BY TRUNC(cdate, 'IW')
ORDER BY week_start;

对于样本数据,输出:

WEEK_START TOTAL_数量
2023-11-27 00:00:00 13
2023-12-04 00:00:00 7
2023-12-11 00:00:00 66

并在您用来连接数据库的任何第三方客户端应用程序(即 C#、PHP、Java、Python 等)中旋转输出,并且您可以在该第三方软件中设置列标题。

另一种方法是动态生成 SQL,但更简单的做法是接受 SQL 不是您想要的输出的工具,并在可以轻松处理转置行和列的任务的第三方应用程序中执行此操作。

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.