我需要编写一个预言机查询来查找 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 查询来查找 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 不是您想要的输出的工具,并在可以轻松处理转置行和列的任务的第三方应用程序中执行此操作。