我使用SSRS报告构建器应用程序为我的系统创建BI报告,该报告跟踪每个月记录和关闭的事件数。
以下是我需要创建查询的表
Month Logged Received Closed Remaining
January 200 220 150 70
February 150 220 200 20
March 110 130 100 30
April 200 230 200 30
,每列定义如下:
已记录=当前月份的未结事件,例如2014年1月1日至2014年1月31日期间开放(仅包含当前月份数据)
收到=记录事件+前几个月的剩余时间仍未结束,例如月份febreuary将为150当前飞蛾+上一个月剩余70将给我总共220收到。
已关闭=在当月开立并在当月结束的事件+本月结束的上个月的剩余事件
剩余=已收到 - 已关闭
我使用的代码并没有给我前几个月的紧急事件,也只是给了我当月关闭的事件
以下是我用于查询的代码:
SELECT group_id, YEAR(Opendate) AS Year, MONTH(Opendate) AS Month,
COUNT(CASE WHEN Month(Closedate) = Month(Opendate)
AND Month(closedate)> Month (opendate) THEN 1 ELSE NULL END) AS closed,
COUNT(*) AS Logged,
FROM Incidents
WHERE (Opendate >= @YearStart) AND (Opendate <= @YearEnd)
GROUP BY YEAR(Opendate), MONTH(Opendate), group_id
ORDER BY Year, Month,group_id
记录正常工作已关闭,收到并且剩下我被卡住了。
我尝试使用Union
并获取了记录和关闭数据
Select count(*) logged,year(opendate) as year1,MONTH(opendate) as
month1,'Logged' as status1
From Incidents
where opendate is not null
GROUP BY year(opendate),MONTH(opendate)
UNION
Select count(*) closed,year(Closedate) as year1,MONTH(Closedate) as
month1,'All_Closed' as status1
From Incidents
where Closedate is not null
GROUP BY year(Closedate),MONTH(Closedate)
UNION
Select count(*) Remaining,year(opendate) as year1,MONTH(opendate) as
month1,'Current_Month_Not_Closed' as status1
From Incidents
where Month(Closedate) > MONTH(Opendate)
GROUP BY year(opendate),MONTH(opendate)
UNION
Select count(*) Month_Closed,year(opendate) as year1,MONTH(opendate) as
month1,'Current_Month_Close' as status1
From Incidents
where MONTH(Closedate) = MONTH(Opendate)
GROUP BY year(opendate),MONTH(opendate)
order by year1,month1
我收到的数据如下:
logged | year1 | month1 | status1
-------+-------+--------+-------------------------
1093 | 2014 | 1 | Logged
1089 | 2014 | 1 | All_Closed
997 | 2014 | 1 | Current_Month_Close
96 | 2014 | 1 | Current_Month_Not_Closed
1176 | 2014 | 2 | Logged
1176 | 2014 | 2 | All_Closed
91 | 2014 | 2 | Current_Month_Not_Closed
1085 | 2014 | 2 | Current_Month_Close
1340 | 2014 | 3 | Logged
1327 | 2014 | 3 | All_Closed
107 | 2014 | 3 | Current_Month_Not_Closed
1232 | 2014 | 3 | Current_Month_Close
116 | 2014 | 4 | Current_Month_Not_Closed
1320 | 2014 | 4 | Current_Month_Close
1424 | 2014 | 4 | All_Closed
1441 | 2014 | 4 | Logged
1167 | 2014 | 5 | Current_Month_Close
105 | 2014 | 5 | Current_Month_Not_Closed
1277 | 2014 | 5 | Logged
1283 | 2014 | 5 | All_Closed
答案 0 :(得分:0)
收到的是在月底之前开设的门票数量,并且在月初之前没有关闭。
count(case when OpenDate <= @EndOfMonth and
(@StartOfMonth >= CloseDate or CloseDate is null) then 1 end)
as Received
关闭非常简单:
count(case when CloseDate between @StartOfMonth and @EndOfMonth
then 1 end) as Closed
您应该能够弄清楚如何使用Google计算一个月的开始和结束时间。
答案 1 :(得分:0)
要获得可靠的数据,日历表作为主播可以提供帮助,如果票证可以在开放日期之后的几个月内存活,或者可能有一个月没有创建票证,则需要这样做。
例如假数据
CREATE TABLE Incidents (
id int identity(1, 1)
, group_id nvarchar(100)
, Opendate Datetime
, Closedate Datetime
)
INSERT INTO Incidents
VALUES ('Service Desk', '20140107', '20140120')
, ('Service Desk', '20140117', '20140123')
, ('Service Desk', '20140127', '20140313')
, ('Service Desk', '20140310', '')
-- from an OP comment the open tickets have the Closedate '' (1900-01-01)
没有日历表(或临时或CTE),即使第三个记录在该月份都是“已接收”和“剩余”,也无法在结果集中添加二月。
要创建日历,有几种方法,在这种情况下,我们需要一些有关月份的信息,但不需要关于日期,因此不会生成这些日期。
declare @YearStart date = '20140101'
declare @YearEnd date = '20140430'
;WITH D(N) AS (
SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7
UNION ALL SELECT 8 UNION ALL SELECT 9
)
SELECT EOM
= DATEADD(D, -1, DATEADD(M, u.N + 10 * t.N + 1
, DATEADD(Y, DATEDIFF(Y, 0, @YearStart), 0)))
, pMonth = u.N + 10 * t.N
FROM D u
CROSS JOIN D t
WHERE u.N + 10 * t.N <= DATEDIFF(M, @YearStart, @YearEnd)
此处EOM
是月末的日期,它将用于检查事件是否在月中关闭,pMonth
是从@YearStart开始的渐进月。< / p>
现在我们需要准备要使用的事件表中的数据
SELECT ID
, OpenDate
, Closedate = COALESCE(NULLIF(Closedate, ''), '99991231')
, pOpenDate = DATEDIFF(M, @YearStart, OpenDate)
, pClosedate = DATEDIFF(M, @YearStart
, COALESCE(NULLIF(Closedate, ''), '99991231'))
FROM Incidents
Closedate
需要始终具有高于OpenDate的值,因为常量日期为9999-12-31
,pOpenDate
和pClosedate
,因为{{1}之前,是@ pMonth
和OpenDate
分别从@YearStart开始的渐进月。
将这些内容设置为可以创建主查询
Closedate
使用declare @YearStart date = '20140101'
declare @YearEnd date = '20140430'
;WITH D(N) AS (
SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7
UNION ALL SELECT 8 UNION ALL SELECT 9
), CM AS (
SELECT EOM
= DATEADD(D, -1, DATEADD(M, u.N + 10 * t.N + 1
, DATEADD(Y, DATEDIFF(Y, 0, @YearStart), 0)))
, pMonth = u.N + 10 * t.N
FROM D u
CROSS JOIN D t
WHERE u.N + 10 * t.N <= DATEDIFF(M, @YearStart, @YearEnd)
), I AS (
SELECT ID
, OpenDate
, Closedate = COALESCE(NULLIF(Closedate, ''), '99991231')
, pOpenDate = DATEDIFF(M, @YearStart, OpenDate)
, pClosedate = DATEDIFF(M, @YearStart
, COALESCE(NULLIF(Closedate, ''), '99991231'))
FROM Incidents
)
SELECT MONTH(CM.EOM) [Month]
, Logged = SUM(CASE WHEN pOpenDate = pMonth
THEN 1
ELSE 0
END)
, Received = Count(i.id)
, Closed = SUM(CASE WHEN pClosedate = pMonth
AND i.Closedate < CM.EOM
THEN 1
ELSE 0
END)
, Remaining = SUM(CASE WHEN i.Closedate > CM.EOM
THEN 1
ELSE 0
END)
FROM CM
INNER JOIN I ON CM.pMonth
BETWEEN i.pOpenDate AND i.pClosedate
WHERE CM.EOM <= @YearEnd
GROUP BY CM.EOM
ORDER BY CM.EOM
从日历表中获取JOIN
和@YearStart
之间的月份以及当月活动的所有事件。它们的属性是使用@YearEnd
逻辑计算的,如果CASE
,如果票证处于活动状态,则会收到它,因此不需要逻辑。
所有Received
都可以在CASE
逻辑
BIT
位逻辑基于declare @YearStart date = '20140101'
declare @YearEnd date = '20140430'
;WITH D(N) AS (
SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7
UNION ALL SELECT 8 UNION ALL SELECT 9
), CM AS (
SELECT EOM
= DATEADD(D, -1, DATEADD(M, u.N + 10 * t.N + 1
, DATEADD(Y, DATEDIFF(Y, 0, @YearStart), 0)))
, pMonth = u.N + 10 * t.N
FROM D u
CROSS JOIN D t
WHERE u.N + 10 * t.N <= DATEDIFF(M, @YearStart, @YearEnd)
), I AS (
SELECT ID
, OpenDate
, Closedate = COALESCE(NULLIF(Closedate, ''), '99991231')
, pOpenDate = DATEDIFF(M, @YearStart, OpenDate)
, pClosedate = DATEDIFF(M, @YearStart
, COALESCE(NULLIF(Closedate, ''), '99991231'))
FROM Incidents
)
SELECT MONTH(CM.EOM) [Month]
, Logged = SUM(1 - CAST(pOpenDate - pMonth AS BIT))
, Received = Count(i.id)
, Closed = SUM(1 - CAST(pClosedate - pMonth AS BIT))
, Remaining = SUM(0 + CAST(i.pClosedate / (CM.pMonth + 1) AS BIT))
FROM CM
INNER JOIN I ON CM.pMonth
BETWEEN i.pOpenDate AND i.pClosedate
WHERE CM.EOM <= @YearEnd
GROUP BY CM.EOM
ORDER BY CM.EOM;
到CAST
的工作方式:
基于此(使用A和B整数):
BIT
时,1 - CAST(A - B AS BIT)
为1
{li> A = B
在CAST(A / (B + 1) AS BIT)
时为{1 A > B
强制隐式转换为0 +
,因为INT
不能BIT
med)