日期差异,T-SQL,票务系统的多行

时间:2016-05-17 19:21:59

标签: sql tsql

我试图获取存储过程来计算故障单打开的时间,包括多次关闭和打开。我的数据如下:

      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

2 个答案:

答案 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'

然后在JOINFeedbackIDIndicator这些表并进行日期汇总。这样我们就可以确保最早的打开记录与每个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,其中案例仍处于打开状态。要处理这些问题,我们可以使用nullCOALESCE() 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