我试图获取存储过程来计算故障单打开的时间,包括多次关闭和打开。我的数据如下:
FeedbackID Open/Closed TimeStamp
2145 Open 2015-11-16 20:23:49.750
2145 Closed 2015-11-23 12:00:35.087
2146 Open 2015-11-16 21:44:59.020
2146 Closed 2015-11-17 12:24:55.843
2146 Open 2015-12-04 13:43:41.830
2146 Closed 2015-12-04 13:45:04.410
2147 Open 2015-11-17 02:39:41.263
2147 Closed 2015-11-23 22:11:33.490
正如您所见,FeedbackID#2146有4个事件。我需要能够计算每个打开和关闭事件之间的差异,然后在有超过2个打开和关闭事件时将它们添加起来。任何帮助表示赞赏!
编辑:发布以下程序的代码
ALTER PROCEDURE [dbo].[spGetOpenCloseFeedbackEvents]
AS
BEGIN
DECLARE @TempTable TABLE (FeedbackID int, [Open/Closed] varchar(20), [TimeStamp] datetime)
DECLARE @UIDTable TABLE (FeedBackID int, [UID] uniqueidentifier)
DECLARE @Open Table (FeedbackID int, [Open/Closed] varchar(20), [TimeStamp] datetime)
DECLARE @Closed Table (FeedbackID int, [Open/Closed] varchar(20), [TimeStamp] datetime)
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
INSERT INTO @TempTable (FeedbackID, [Open/Closed], [TimeStamp])
SELECT * FROM dbo.FeedbackChange
WHERE FeedbackID = FeedbackChange.FeedbackID
AND
[Open/Closed] IS NOT NULL
ORDER BY FeedbackID
INSERT INTO @UIDTable (FeedBackID, [UID])
SELECT FeedbackID, [UID] FROM tblFeedbackRequests fbr
where fbr.FeedbackID = FeedbackID
SELECT * FROM @TempTable t
--JOIN @UIDTable u ON t.FeedbackID = u.FeedBackID
--WHERE u.UID = @UID
Order by t.FeedbackID
SELECT FeedbackID, [Open/Closed], TimeStamp,
ROW_NUMBER() over (partition by FeedBackID order by TimeStamp asc) as [Indicator]
INTO @Open
FROM @TempTable
Where [Open/Closed] = 'Open'
SELECT FeedbackID, [Open/Closed], TimeStamp,
ROW_NUMBER() over (partition by FeedBackID order by TimeStamp asc) as [Indicator]
INTO @Closed
FROM @TempTable
Where [Open/Closed] = 'Closed'
SELECT SUM(DATEDIFF(day,o.TimeStamp,c.TimeStamp)) as "Days Open",
o.FeedbackID
FROM @Open o
INNER JOIN @Closed c on o.FeedbackID = c.FeedbackID and o.[Indicator = c.Indicator
GROUP BY o.FeedbackID
END
答案 0 :(得分:1)
首先,为临时状态创建临时表或CTE,为封闭状态创建另一个临时表或CTE。使用ROW_NUMBER over (partition by FeedBackID order by TimeStamp asc)
创建一个指示符,其中打开状态记录与哪些已关闭记录匹配:
SELECT FeedbackID, [Open/Closed], TimeStamp,
ROW_NUMBER over (partition by FeedBackID order by TimeStamp asc) as "Indicator"
INTO @Open
FROM Table
WHERE [Open/Closed] = 'Open'
SELECT FeedbackID, [Open/Closed], TimeStamp,
ROW_NUMBER over (partition by FeedBackID order by TimeStamp asc) as "Indicator"
INTO @Closed
FROM Table
WHERE [Open/Closed] = 'Closed'
然后在JOIN
和FeedbackID
上Indicator
这些表并进行日期汇总。这样我们就可以确保最早的打开记录与每个FeedbackID
的最早已关闭记录相符:
SELECT SUM(DATEDIFF(day,o.TimeStamp,c.TimeStamp)) as "Days Open",
o.FeedbackID
FROM @Open o
INNER JOIN @Closed c on o.FeedbackID = c.FeedbackID and o.Indicator = c.Indicator
GROUP BY o.FeedbackID
此时,您应该有[{1}}个差异,包含在TimeStamp
中,并按SUM()
分组,以查看FeedbackID
开启/关闭超过1的情况集。
编辑:对仍处于打开状态的案例进行核算
要处理仍处于打开状态的案例,我们首先需要将FeedbackID
更改为INNER JOIN
,这样我们就不会丢失缺少匹配“已关闭”记录的“开放”记录。< / p>
LEFT JOIN
但是,这将填充SELECT SUM(DATEDIFF(day,o.TimeStamp,c.TimeStamp)) as "Days Open",
o.FeedbackID
FROM @Open o
LEFT JOIN @Closed c on o.FeedbackID = c.FeedbackID and o.Indicator = c.Indicator
GROUP BY o.FeedbackID
c.TimeStamp
,其中案例仍处于打开状态。要处理这些问题,我们可以使用null
将COALESCE()
null
字段替换为更有意义的字段。由于这些案例仍处于开放状态,我们不妨使用c.TimeStamp
并计算他们开放的时间:
GETDATE()
答案 1 :(得分:0)
这是我在Aaron D的帮助下的最终答案。 感谢所有的帮助:)
DECLARE @TempTable TABLE (FeedbackID int, [Open/Closed] varchar(20), [TimeStamp] datetime)
DECLARE @UIDTable TABLE (FeedBackID int, [UID] uniqueidentifier)
DECLARE @Open Table (FeedbackID int, [Open/Closed] varchar(20), [TimeStamp] datetime, [Indicator] int)
DECLARE @Closed Table (FeedbackID int, [Open/Closed] varchar(20), [TimeStamp] datetime, [Indicator] int)
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
INSERT INTO @TempTable (FeedbackID, [Open/Closed], [TimeStamp])
SELECT * FROM dbo.FeedbackChange
WHERE FeedbackID = FeedbackChange.FeedbackID
AND
[Open/Closed] IS NOT NULL
ORDER BY FeedbackID
INSERT INTO @UIDTable (FeedBackID, [UID])
SELECT FeedbackID, [UID] FROM tblFeedbackRequests fbr
where fbr.FeedbackID = FeedbackID
INSERT INTO @Open (FeedbackID, [Open/Closed], [TimeStamp],Indicator)
SELECT FeedbackID, [Open/Closed], TimeStamp, ROW_NUMBER() over (partition by FeedBackID order by TimeStamp asc) as [Indicator]
FROM @TempTable
Where [Open/Closed] = 'Open'
INSERT INTO @Closed (FeedbackID, [Open/Closed], [TimeStamp],Indicator)
SELECT FeedbackID, [Open/Closed], TimeStamp, ROW_NUMBER() over (partition by FeedBackID order by TimeStamp asc) as [Indicator]
FROM @TempTable
Where [Open/Closed] = 'Closed'
SELECT SUM(DATEDIFF(HOUR,o.TimeStamp,c.TimeStamp)) as "Days Open", o.FeedbackID
FROM @Open o
INNER JOIN @Closed c on o.FeedbackID = c.FeedbackID and o.[Indicator] = c.Indicator
GROUP BY o.FeedbackID