SQL查询来计算日期范围内的项目?
Posted
技术标签:
【中文标题】SQL查询来计算日期范围内的项目?【英文标题】:SQL Query to Count Items Within Date Range? 【发布时间】:2020-02-12 16:20:19 【问题描述】:首先,我知道在这一点上足以让自己陷入困境。我正在为 AS/400 系统编写查询。我有一个包含开始日期和结束日期的文件。我想要做的是创建一个查询,可以计算在某个日期范围内打开了多少行项目。 (对于我的应用程序打开定义为:DATE > START_DATE
AND (DATE <= END_DATE OR END_DATE = '0'
))。我可以手动设置“日期”,但我正试图返回并从历史上批量提取这些信息。我遇到的问题是让它针对日期列表运行此查询。我想要的是输入历史间隔(比如CURRENT_DATE - 5
)并输出:
Date Open
20200206 30,000
20200207 31,000
20200210 29,675
20200211 31,375
20200212 32,000
我用于“一次一天”的查询:
SELECT
COUNT(*)
FROM
MYFILE
WHERE
START_DATE < '20200210'
AND (
END_DATE >= '20200210'
OR END_DATE = '0'
)
这很好用,但很耗时。从这里我不知道如何转换到所需的输出......或者即使有可能......但它会加快我的速度。提前致谢。
附:欢迎任何帮助,如果您知道如何在 mysql 等中完成此操作,请分享。我可以使用它并运行它以使其专门为 AS/400 工作。这就是我现在所处的位置。
**************** 编辑澄清 1. 当前代码 提供的当前代码就是我所拥有的。我不知道从哪里开始 关于我的要求。 2. 示例数据:
Line Item START_DATE END_DATE
1 20200206 20200210
2 20200207 20200210
3 20200207 20200207
-
预期输出:
DATE COUNT
20200205 0
20200206 0
20200207 1
20200210 2
20200211 0
-
DBMS 我已更新标签以包含 DB2。 5. 我不相信 GROUP BY 会起作用。
基本上我正在寻找以迭代式的方式计算它。来自我的 python/java 背景,这对我来说很有意义。我不是在寻找 5 天前打开的所有内容,我想从 5 天前开始计算这 5 天中每天打开的订单项数量。如果 GROUP 实际上可以做到这一点,请详细说明并向我展示我的方式的错误。与此同时,我将开始为此进行分组。
【问题讨论】:
嗨,欢迎来到 Stack Overflow。请阅读***.com/help/minimal-reproducible-example 和***.com/help/how-to-ask。在这个示例中,我们需要查看您当前的代码,示例数据至关重要。此外,查看您的代码产生的结果与您的预期结果是非常有益的。请参阅:meta.***.com/questions/271055/…。另外,您使用的是什么DBMS
?请用那个标记你的问题(我想你提到了mySQL
)
如果我没记错的话,AS/400 是 IBM 的 DB2 正确吗?如果是这样的话,你能用 DB2 更新问题标签吗?
【参考方案1】:
下面是一个查询,返回给定日期和给定日期之间的连续日期 - 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|
这种“虚拟表”的进一步使用是显而易见的:您可以将LEFT JOIN
与B.START_DATE < DEC(TO_CHAR(T.DT, 'YYYYMMDD'), 8) AND DEC(TO_CHAR(T.DT, 'YYYYMMDD'), 8) <= B.END_DATE
上的基表一起按T.DT
分组结果。
【讨论】:
SELECT M.MY_DAY,COUNT(*) FROM (SELECT DISTINCT(START_DATE) AS MY_DAY FROM MYFILE WHERE START_DATE >= REPLACE(CHAR(CURRENT DATE - 5 DAY, ISO),'-',' ') ORDER BY START_DATE) AS M LEFT JOIN MYFILE P ON M.MY_DAY > P.START_DATE AND (M.MY_DAY 这是最后的查询。谢谢你的帮助,我不知道条件加入可以这样使用。我投了你一票,但我太新了,我的选票无法计算。【参考方案2】:请试试这个:
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')
【讨论】:
【参考方案3】:听起来像是group by
语句的简单用法,但你没有说明你是按哪一列分组的,只是一个日期,我假设为 START_DATE
我不知道 AS/400 SQL,所以我将稍微抽象一点,并假设 CURRENT_DATE() 返回您所在地区的当前日期。 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
【讨论】:
【参考方案4】:取消透视数据并使用窗口函数进行聚合。思路如下:
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
中考虑到这一点。
这不计算某人离开的那天。如果要计算它们,只需在子查询中的 end_date
中添加 1 天即可。
【讨论】:
以上是关于SQL查询来计算日期范围内的项目?的主要内容,如果未能解决你的问题,请参考以下文章
SQL - 显示给定范围内的所有日期,并使用数据库中的时间戳计算该日期有多少帖子