【发布时间】:2020-08-13 17:56:02
【问题描述】:
我有一个 SQL Server 表,其中包含 12 个月前的任务数据。
这是一个例子:
我正在尝试编写一个查询,该查询显示每个月以及在该月之前按其评级打开的票数。下面的输出示例:
我创建了以下 SQL 语句来按天计数:
SELECT
created,
COUNT(CASE WHEN rating = ‘high’ THEN 1 ELSE NULL END) AS high,
COUNT(CASE WHEN rating = ‘med’ THEN 1 ELSE NULL END) AS med,
COUNT(CASE WHEN rating = ‘low’ THEN 1 ELSE NULL END) AS low
FROM
taskDB
GROUP BY
created
ORDER BY
created ASC
我不确定如何按月分组并在该月之前获得正确的计数?有一个更好的方法吗?我的最终目标是将这些数据显示为时间线图,其中 yAxis 是票数,xAxis 是日期(年/月)。每个“评分”都会有一行。
2020 年 8 月 14 日更新
我在那里尝试了几个答案,他们似乎只计算每个月开放的门票数量,而不是每个月 + 之前所有月份的门票数量。我用一些测试数据创建了一个 SQL 脚本,这样每个人都可以看到我正在使用的内容:
GO
CREATE TABLE [dbo].[taskDB](
[ticket] [varchar](50) NULL,
[created] [date] NULL,
[closed] [date] NULL,
[rating] [varchar](50) NULL
) ON [PRIMARY]
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023345', CAST(N'2019-09-01' AS Date), CAST(N'2020-01-17' AS Date), N'Low')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023346', CAST(N'2019-08-01' AS Date), CAST(N'2019-08-03' AS Date), N'Critical')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023347', CAST(N'2019-09-01' AS Date), CAST(N'2019-09-20' AS Date), N'Critical')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023348', CAST(N'2019-08-01' AS Date), CAST(N'2020-08-06' AS Date), N'Critical')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023349', CAST(N'2020-08-01' AS Date), CAST(N'2020-08-05' AS Date), N'Medium')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023350', CAST(N'2019-08-01' AS Date), CAST(N'2019-08-05' AS Date), N'Medium')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023351', CAST(N'2019-12-22' AS Date), CAST(N'' AS Date), N'High')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023352', CAST(N'2019-11-07' AS Date), CAST(N'2020-08-05' AS Date), N'Medium')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023353', CAST(N'2020-08-02' AS Date), CAST(N'' AS Date), N'Low')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023354', CAST(N'2019-08-02' AS Date), CAST(N'2019-08-05' AS Date), N'Medium')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023355', CAST(N'2019-010-02' AS Date), CAST(N'' AS Date), N'Low')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023356', CAST(N'2019-08-02' AS Date), CAST(N'2019-08-05' AS Date), N'Critical')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023357', CAST(N'2019-08-06' AS Date), CAST(N'2020-07-05' AS Date), N'Critical')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023358', CAST(N'2019-10-04' AS Date), CAST(N'' AS Date), N'Low')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023359', CAST(N'2019-12-02' AS Date), CAST(N'2020-02-25' AS Date), N'High')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023360', CAST(N'2019-08-05' AS Date), CAST(N'2019-08-05' AS Date), N'Medium')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023361', CAST(N'2020-08-02' AS Date), CAST(N'' AS Date), N'High')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023362', CAST(N'2019-09-02' AS Date), CAST(N'2019-10-06' AS Date), N'Critical')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023363', CAST(N'2019-10-03' AS Date), CAST(N'2019-11-08' AS Date), N'High')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023365', CAST(N'2019-10-03' AS Date), CAST(N'2019-12-08' AS Date), N'N/A')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023364', CAST(N'2019-11-03' AS Date), CAST(N'2019-11-05' AS Date), N'High')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023366', CAST(N'2020-06-03' AS Date), CAST(N'' AS Date), N'High')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023368', CAST(N'2019-08-03' AS Date), CAST(N'2019-08-05' AS Date), N'High')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023367', CAST(N'2019-11-03' AS Date), CAST(N'' AS Date), N'N/A')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023371', CAST(N'2019-08-03' AS Date), CAST(N'2019-08-05' AS Date), N'N/A')
GO
INSERT [dbo].[taskDB] ([ticket], [created], [closed], [rating]) VALUES (N'023370', CAST(N'2019-08-03' AS Date), CAST(N'2019-08-05' AS Date), N'Critical')
GO
我从@GMB 尝试了以下内容,结果很接近,但似乎没有给我正确的结果,因为有负数并且空白的封闭字段返回为 1900-01-01。
select
year(x.dt) yyyy,
month(x.dt) mm,
sum(sum(case when x.rating = 'low' then cnt else 0 end))
over(order by year(x.dt), month(x.dt)) low,
sum(sum(case when x.rating = 'medium' then cnt else 0 end))
over(order by year(x.dt), month(x.dt)) medium,
sum(sum(case when x.rating = 'high' then cnt else 0 end))
over(order by year(x.dt), month(x.dt)) high
from [TestDB].[dbo].[taskDB] t
cross apply (values
(rating, created, 1),
(rating, closed, -1)
) as x(rating, dt, cnt)
where x.dt is not null
group by year(x.dt), month(x.dt)
order by year(x.dt), month(x.dt)
此查询的结果:
2020 年 8 月 14 日更新
@iceblade 修改后的查询在这一点上似乎是最正确的。唯一不考虑的是,如果一张票在同一个月内打开和关闭,我认为应该计算在内。这是查询:
declare @FromDate datetime,
@ToDate datetime;
SET @FromDate = (Select min(created) From [dbo].[taskDB]);
SET @ToDate = (Select max(created) From [dbo].[taskDB]);
declare @openTicketsByMonth table (firstDayNextMonth datetime, year int, month int, Low int, Medium int, High int, Critical int, NA int)
Insert into @openTicketsByMonth(firstDayNextMonth, year, month)
Select top (datediff(month, @FromDate, @ToDate) + 1)
dateadd(month, number + 1, @FromDate),
year(dateadd(month, number, @FromDate)),
month(dateadd(month, number, @FromDate))
from [master].dbo.spt_values
where [type] = N'P' order by number;
update R
Set R.Low = (Select count(1) from [dbo].[taskDB] where rating = 'Low' and created < R.firstDayNextMonth and (closed >= R.firstDayNextMonth or closed = '' or closed is null)),
R.Medium = (Select count(1) from [dbo].[taskDB] where rating = 'Medium' and created < R.firstDayNextMonth and (closed >= R.firstDayNextMonth or closed = '' or closed is null)),
R.High = (Select count(1) from [dbo].[taskDB] where rating = 'High' and created < R.firstDayNextMonth and (closed >= R.firstDayNextMonth or closed = '' or closed is null)),
R.Critical = (Select count(1) from [dbo].[taskDB] where rating = 'Critical' and created < R.firstDayNextMonth and (closed >= R.firstDayNextMonth or closed = '' or closed is null)),
R.NA = (Select count(1) from [dbo].[taskDB] where rating = 'N/A' and created < R.firstDayNextMonth and (closed >= R.firstDayNextMonth or closed = '' or closed is null))
From @openTicketsByMonth R
select year,
month,
Low,
Medium,
High,
Critical,
NA
from @openTicketsByMonth
以及基于上述数据的查询输出:
如果您查看 2019/8 年度,则有 2 张重要票证在该月之后已打开并保持打开状态,但有 3 张重要票证在同一月打开和关闭。我认为这些都应该算在内。
2020 年 8 月 17 日更新
@iceblade 发布的查询已被编辑并确认产生正确的结果。答案已相应标记。
【问题讨论】:
-
请详细说明“我正在尝试编写一个查询,以显示每个月以及该月之前按其评级开放的门票数量。”。
-
所以让我们以上个月为例,如果我运行一个查询来显示所有打开的门票,那么我想显示所有打开的门票,按评级显示上个月的所有打开门票,依此类推,逐月返回.
标签: sql sql-server database tsql