在 SQL 中创建用于迭代的行
Create rows for iteration in 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
表达式。
Here 是一个 db<>fiddle.
我必须创建一个报告,说明每个月的第一天工单打开了多长时间,另一个报告显示工单关闭需要多长时间。在不为每个月创建间隔的情况下使用 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
表达式。
Here 是一个 db<>fiddle.