在 DB2 SQL 中使用 Stored Procedures/Macros 声明和循环

Declare and Loop using Stored Procedures/Macros in DB2 SQL

我有一个 table_A,其名称和交货日期如下

Name Del_dt
Mark 2022-04-01
Mark 2022-04-03
Mark 2022-04-05
Mark 2022-04-07
Mark 2022-04-09
Dave 2022-04-02
Dave 2022-04-04
Dave 2022-04-06
Dave 2022-04-08
Dave 2022-04-10

等等。我想要一个特定日期的 Name 的累计计数。例如日期从 2022-04-07 到 2022-04-10

的输出样本
Date Name cul_cnt
2022-04-07 Mark 4
2022-04-08 Mark 4
2022-04-09 Mark 5
2022-04-10 Mark 5
2022-04-07 Dave 3
2022-04-08 Dave 4
2022-04-09 Dave 4
2022-04-10 Dave 5

当然,不同名称的日期可以相同。我正在尝试使用 Dynamic SQL(因为我是初学者,想探索更多)。我根据我能找到的有关 Dynamic SQL 方法的内容生成了以下代码。我也对其他方法持开放态度。

begin
    declare cur_date date;
    declare og_date date;
    declare Cust_Name varchar2(4);
    declare cul_cnt number;
    set cur_date = current_date; /*today's date*/
    set og_date = cur_date - 10; /*calculating cumulative counts for last 10 days*/
loop
    select Name,count(Name) into Cust_Name,cul_cnt,og_date
    from table_A
    where prod_type like 'SHOES' /*Another column in the table just for filter*/
    and Del_dt <= og_date
    group by Name;
    og_date = og_date + 1;
exit when (og_date > cur_date);
end;
end;

目前我遇到这个错误

Error report -
Error starting at line : 1 in command -
DB2 SQL Error: SQLCODE=-104, SQLSTATE=42601, SQLERRMC=CUR_DATE;SECTION, DRIVER=3.69.49

不过,我敢肯定代码中会有更多错误。如何获得所需的输出,如输出 table 所示。另外,我如何获得 og_date(输出中的日期列),因为它不存在于原始 table_A 中,而是定义的变量

试试这个:

 WITH 
-- Table of 10 dates generation starting from 2022-04-10
-- CURRENT_DATE can be used instead   
  D (I, DT) AS 
(
  SELECT 1, DATE ('2022-04-10') FROM SYSIBM.SYSDUMMY1
    UNION ALL
  SELECT I + 1, DT - 1 DAY FROM D WHERE I < 10
)
/*
, table_A (Name, Del_dt) AS 
(
          SELECT 'Mark', DATE ('2022-04-01') FROM SYSIBM.SYSDUMMY1
UNION ALL SELECT 'Mark', DATE ('2022-04-03') FROM SYSIBM.SYSDUMMY1
UNION ALL SELECT 'Mark', DATE ('2022-04-05') FROM SYSIBM.SYSDUMMY1
UNION ALL SELECT 'Mark', DATE ('2022-04-07') FROM SYSIBM.SYSDUMMY1
UNION ALL SELECT 'Mark', DATE ('2022-04-09') FROM SYSIBM.SYSDUMMY1
UNION ALL SELECT 'Dave', DATE ('2022-04-02') FROM SYSIBM.SYSDUMMY1
UNION ALL SELECT 'Dave', DATE ('2022-04-04') FROM SYSIBM.SYSDUMMY1
UNION ALL SELECT 'Dave', DATE ('2022-04-06') FROM SYSIBM.SYSDUMMY1
UNION ALL SELECT 'Dave', DATE ('2022-04-08') FROM SYSIBM.SYSDUMMY1
UNION ALL SELECT 'Dave', DATE ('2022-04-10') FROM SYSIBM.SYSDUMMY1
)
*/
SELECT D.DT, A.Name, A.cul_cnt
FROM D
CROSS JOIN TABLE 
(
  SELECT A.Name, COUNT (1) cul_cnt
  FROM table_A A
  WHERE A.Del_dt <= D.DT
  GROUP BY A.Name
) A
WHERE DT BETWEEN DATE ('2022-04-07') AND DATE ('2022-04-10')
ORDER BY A.Name DESC, D.DT

如果您取消对注释掉的块的注释,您可以 运行 语句原样。本例中的结果与您的结果相同:

DT NAME CUL_CNT
2022-04-07 Mark 4
2022-04-08 Mark 4
2022-04-09 Mark 5
2022-04-10 Mark 5
2022-04-07 Dave 3
2022-04-08 Dave 4
2022-04-09 Dave 4
2022-04-10 Dave 5

Oracle 中的相同查询:

WITH
  D (I, DT) AS 
(
  SELECT 1, TO_DATE ('2022-04-10', 'YYYY-MM-DD') FROM DUAL
    UNION ALL
 SELECT I + 1, DT - INTERVAL '1' DAY FROM D WHERE I < 10
)
/*
, table_A (Name, Del_dt) AS 
(
          SELECT 'Mark', TO_DATE ('2022-04-01', 'YYYY-MM-DD') FROM DUAL
UNION ALL SELECT 'Mark', TO_DATE ('2022-04-03', 'YYYY-MM-DD') FROM DUAL
UNION ALL SELECT 'Mark', TO_DATE ('2022-04-05', 'YYYY-MM-DD') FROM DUAL
UNION ALL SELECT 'Mark', TO_DATE ('2022-04-07', 'YYYY-MM-DD') FROM DUAL
UNION ALL SELECT 'Mark', TO_DATE ('2022-04-09', 'YYYY-MM-DD') FROM DUAL
UNION ALL SELECT 'Dave', TO_DATE ('2022-04-02', 'YYYY-MM-DD') FROM DUAL
UNION ALL SELECT 'Dave', TO_DATE ('2022-04-04', 'YYYY-MM-DD') FROM DUAL
UNION ALL SELECT 'Dave', TO_DATE ('2022-04-06', 'YYYY-MM-DD') FROM DUAL
UNION ALL SELECT 'Dave', TO_DATE ('2022-04-08', 'YYYY-MM-DD') FROM DUAL
UNION ALL SELECT 'Dave', TO_DATE ('2022-04-10', 'YYYY-MM-DD') FROM DUAL
)
*/
SELECT TO_CHAR (D.DT, 'YYYY-MM-DD') DT, A.Name, A.cul_cnt
FROM D
CROSS JOIN LATERAL 
(
  SELECT A.Name, COUNT (1) cul_cnt
  FROM table_A A
  WHERE A.Del_dt <= D.DT
  GROUP BY A.Name
) A
WHERE D.DT BETWEEN TO_DATE ('2022-04-07', 'YYYY-MM-DD') AND TO_DATE ('2022-04-10', 'YYYY-MM-DD')
ORDER BY A.Name DESC, D.DT