sql - 在 SQL 中为迭代创建行
问题描述
我必须创建一个报告,说明每个月的第一天一张票打开多长时间,另一个显示关闭一张票需要多长时间。在不为每个月创建间隔的情况下,使用 SQL 执行此操作的最佳方法是什么?我正在使用 SQL Server 2008 R2
我目前的数据:
| Ticket | Start Date | End Date |
|--------|------------|------------|
| ABC | 5/8/2018 | 9/28/2018 |
| XYZ | 6/22/2018 | 10/15/2018 |
预期结果:
| Ticket | Start Date | End Date | Report Date | Ticket Age | Ticket Interval |
|--------|------------|------------|-------------|------------|-----------------|
| ABC | 5/8/2018 | 9/28/2018 | 6/1/2018 | 24 | |
| ABC | 5/8/2018 | 9/28/2018 | 7/1/2018 | 54 | |
| ABC | 5/8/2018 | 9/28/2018 | 8/1/2018 | 85 | |
| ABC | 5/8/2018 | 9/28/2018 | 9/1/2018 | 116 | |
| ABC | 5/8/2018 | 9/28/2018 | 10/1/2018 | | 143 |
| XYZ | 6/22/2018 | 10/15/2018 | 7/1/2018 | 9 | |
| XYZ | 6/22/2018 | 10/15/2018 | 8/1/2018 | 40 | |
| XYZ | 6/22/2018 | 10/15/2018 | 9/1/2018 | 71 | |
| XYZ | 6/22/2018 | 10/15/2018 | 10/1/2018 | 101 | |
| XYZ | 6/22/2018 | 10/15/2018 | 11/1/2018 | | 115 |
解决方案
您可以使用递归 CTE:
with cte as (
select ticket, sdate, edate, dateadd(month, 1, dateadd(day, 1 - day(sdate), sdate)) as reportdate
from t
union all
select ticket, sdate, edate, dateadd(month, 1, reportdate)
from cte
where reportdate <= edate
)
select cte.*, datediff(day, sdate, reportdate) as ticketage,
(case when datediff(month, edate, reportdate) = 1 then datediff(day, sdate, edate) end) as interval
from cte
order by ticket, reportdate;
我在票的最后一个月包括了票龄。case
如果您真的不想要它,您可以使用类似的表达方式。
这是一个 db<>fiddle。
推荐阅读
- c++ - 从排序列表中删除重复项(新方法)
- for-loop - Julia 中的 for 循环。语法混乱
- reactjs - 如何在 react-typescript 中设置 HOC 中的道具类型?
- delphi - 将假设备添加到 Windows 设备管理器
- python - 使用 Celery 和 Redis 调用 Django 自定义管理命令输出“未知命令”错误
- apache - 虚拟主机配置在 Centos 8 Apache 2.4 中不起作用
- android - notifyDataSetChanged 和 toMutableList 不起作用 (Kotlin)
- c# - 在mongodb中合并父字段及其嵌套数组字段
- python - PyPI 包测试:来自 https://test.pypi.org/legacy/ 的 403 Forbidden
- python - mongodb '$exists' 不保留我同事计算机中的所有字段,但保留我的所有字段