SQL 查询以计算日期范围内的项目?

SQL Query to Count Items Within Date Range?

首先,我现在所知道的足以让自己陷入麻烦。我正在为 AS/400 系统编写查询。我有一个包含开始日期和结束日期的文件。我想要做的是创建一个查询,该查询可以计算在某个日期范围内打开了多少行项目。 (对于我的应用程序,打开定义为:DATE > START_DATE AND (DATE <= END_DATE OR END_DATE = '0'))。我可以通过手动设置 "DATE" 获得此功能,但我正在尝试返回并从历史上批量提取此信息。我遇到的问题是 运行 这个查询针对日期列表。我想要的是输入历史间隔(比如CURRENT_DATE - 5)并输出:

Date             Open
20200206         30,000
20200207         31,000
20200210         29,675
20200211         31,375
20200212         32,000

我用于 'one-day-at-a-time' 查询的内容:

SELECT
        COUNT(*) 
    FROM
        MYFILE
    WHERE 
        START_DATE < '20200210' 
    AND (
            END_DATE >= '20200210' 
        OR  END_DATE = '0'
        )

这很好用,但很耗时。从这里我不知道如何过渡到所需的输出......或者即使可能......但它会加快我的速度。提前致谢。

P.S。欢迎任何帮助,如果您知道如何在 mySQL 等中完成此操作,请分享。我可以把它和 运行 结合起来,让它专门为 AS/400 工作。我就是这样走到现在的。

****************** 编辑澄清 1. 当前代码 提供的当前代码是我所拥有的。我不知道从哪里开始 关于我的要求。 2. 示例数据:

Line Item       START_DATE        END_DATE
1               20200206          20200210
2               20200207          20200210
3               20200207          20200207
  1. 预期输出:
DATE           COUNT
20200205       0
20200206       0
20200207       1
20200210       2
20200211       0
  1. DBMS 我更新了标签以包含 DB2。 5. 我认为 GROUP BY 行不通。
    基本上我正在寻找以迭代式方式计算的结果。从我的 python/java 背景来看,这对我来说很有意义。我不是在寻找 5 天前打开的所有内容,我想从 5 天前开始计算这 5 天中每一天打开的订单项数量。如果这实际上可以通过 GROUP 实现,请详细说明并告诉我我的方法的错误。同时,我要开始搞乱分组了。

请试试这个:

SELECT COUNT(*) FROM MYFILE WHERE (START_DATE < '20200205' AND (END_DATE >= '20200210' OR END_DATE = '0')) GROUP BY DATE_FORMAT(START_DATE , '%Y%m%d')

听起来像是对 group by 语句的简单使用,但您没有说明要分组的列,只是一个日期,我假设 START_DATE

我不知道 AS/400 SQL 所以我会有点抽象并假设 CURRENT_DATE() returns 当前日期语言环境。 RDBMS 在这方面有所不同。

鉴于这些假设,类似以下内容应该有所帮助:


SELECT
        START_DATE as DATE,
        COUNT(*) as OPEN
    FROM
        MYFILE
    WHERE 
        START_DATE >= (CURRENT_DATE() - 5)
    AND (
            END_DATE >= (CURRENT_DATE() - 5)
        OR  END_DATE = '0'
        )
    GROUP BY
        START_DATE

逆透视数据并使用 window 函数进行聚合。这是想法:

with se as (
      select dte, sum(ins) as ins, sum(outs) as outs
      from ((select start_date as dte, count(*) as ins, 0 as outs
             from t
            ) union all
            (select end_date, 0, count(*) as outs
             from t
            )
           )
select dte, ins, outs,
       (sum(sum(ins)) over (order by dte) -
        sum(sum(outs)) over (order by dte)
       )
from se
order by dte;

这会将给定日期的所有开始次数相加并减去结束次数。

备注:

  • 如果要按日期过滤,请将过滤逻辑放在 outer 查询中。
  • 这假设所有日期都有效。如果某些日期比较特殊,您需要在 order by.
  • 中考虑到这一点
  • 这不包括离开当天的人数。如果要计算它们,只需将 1 天添加到子查询中的 end_date

下面是一个返回给定日期和给定日期之间的连续日期的查询 - 5 天。当然,您可以使用 CURRENT DATE 而不是这个常量。

WITH T (DT) AS 
(
VALUES DATE('2020-02-13') - 5 DAYS
  UNION ALL
SELECT DT + 1 DAY
FROM T 
WHERE DT < DATE('2020-02-13')
)
SELECT DT FROM T;

结果是:

|DT        |
|----------|
|2020-02-08|
|2020-02-09|
|2020-02-10|
|2020-02-11|
|2020-02-12|
|2020-02-13|

这种 "virtual table" 的进一步用法是显而易见的:您可以 LEFT JOIN 它与 B.START_DATE < DEC(TO_CHAR(T.DT, 'YYYYMMDD'), 8) AND DEC(TO_CHAR(T.DT, 'YYYYMMDD'), 8) <= B.END_DATE 上的基础 table 一起将结果按 T.DT 分组。