【问题标题】:Get difference between two times for SQL Server 2012获取 SQL Server 2012 的两次之间的差异
【发布时间】:2017-08-15 19:46:01
【问题描述】:

背景:

我正在尝试确定客户在特定房间中花费的时间长度。每个客户都可以通过CustomerID 识别,当他们访问时,他们会被分配一个VisitNumber。例如,如果客户今天访问,他们会收到 VisitNumber,例如 111111。然后他们会离开并在下周回来,并会收到 VisitNumber,即 111112。

当客户第一次访问时,他们最初并没有被分配一个房间,当他们最终被分配到他们指定的房间时,一个条目被写入数据库。 CurrentRoom 将是空白的,因为他们还没有房间,NewRoom 是他们已经搬进的房间。

该条目将被记录为事件 1(客户从没有房间移动到房间),并且时间是交易发生的时间。如果客户在其现有住宿期间被移动,这将被记录为事件 9(客户从一个房间移动到另一个房间),CurrentRoom 和 *NewRoom 值将也被记录下来。

问题

我已经使用 LAGLEAD 然后计算出两次之间的差异,这就是客户在那个特定房间度过的时间长度。

使用 LAG 时的问题是它正在获取先前的值,在某些情况下可能是来自完全不同的客户的值。我想仅获取特定 CustomerID 和当前 VisitNumberLAGLEAD 值,然后计算出这些值之间的差异以了解如何客户在房间里待了多久。

演示数据:

CREATE TABLE #beds
(
    [id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
     [User] [nvarchar](50) NULL,
    [CustomerID] [nvarchar](50) NULL,
     [Area] [nchar](10) NULL,
    [Event] [nvarchar](50) NULL,
    [VisitNumber] [nvarchar](50) NULL,
    [Time] [datetime] NULL,
     [CurrentRoom] [nvarchar](50) NULL,
     [NewRoom] [nvarchar](50) NULL
)
GO

INSERT INTO #beds ([User],[CustomerID],[Area],[Event],[VisitNumber],[Time],[CurrentRoom],[NewRoom])
VALUES ('00001','C11111111','Area1',2,111111111,'2017-03-22 11:05:44.360','B22','B44'),
('00001','C11111111','Area1',1,111111111,'2017-03-22 11:05:15.517','','B22'),
('00001','C22222222','Area2',1,222222222,'2017-03-22 07:38:16.117','','POD3'),
('00001','C22222222','Area2',3,222222222,'2017-03-22 07:41:24.787','POD3','POD3'),
('00001','C22222222','Area2',9,222222222,'2017-03-22 09:10:49.697','POD3',''),
('00001','C22222222','Area2',1,222222222,'2017-03-22 10:05:19.130','','POD15'),
('00001','C22222222','Area2',2,222222222,'2017-03-22 10:13:43.057','POD15','A'),
('00001','C22222222','Area2',3,222222222,'2017-03-22 10:25:01.527','A','A'),
('00001','C22222222','Area2',3,222222222,'2017-03-22 10:46:03.960','A','A'),
('00001','C22222222','Area2',3,222222222,'2017-03-22 10:46:17.030','A','A'),
('00002','C33333333','Area3',1,333333333,'2017-03-22 09:20:23.660','','B46'),
('00001','C33333333','Area2',9,333333333,'2017-03-22 08:53:32.860','POD8','POD1'),
('00001','C33333333','Area2',1,333333333,'2017-03-22 07:34:58.810','POD7','POD8'),
('00001','C33333333','Area2',1,333333333,'2017-03-22 11:49:55.203','','BB4'),
('00001','C33333333','Area2',3,333333333,'2017-03-22 11:50:11.943','BB4','BB4'),
('00001','C33333333','Area2',3,333333333,'2017-03-22 08:42:56.157','POD8','POD8'),
('00001','C33333333','Area2',3,333333333,'2017-03-22 08:22:59.157','POD8','POD8'),
('00003','C33333333','Area3',1,333333333,'2017-03-23 06:41:12.753','','B46')

GO

这是我目前的查询;这会给我上一行值和下一行值,但我认为它没有考虑到客户。

SELECT
    T1.[User], T1.[CustomerID],
    T1.[Area], T1.[Event],
    T1.[VisitNumber],
    T1.[CurrentRoom], T1.[NewRoom],
    T1.[Time],
    LAG(T1.TIME) OVER (ORDER BY T1.VisitNumber) PreviousTime,
    LEAD(T1.TIME) OVER (ORDER BY T1.VisitNumber) NextTime
FROM
    #beds t1
WHERE
    T1.[Area] = 'Area2'
    AND T1.[CurrentRoom] IS NOT NULL
    AND T1.[NewRoom] IS NOT NULL
    AND T1.[CustomerID] IS NOT NULL
    AND T1.[CustomerID] <> ' '
    AND T1.Event IN (1,9)
ORDER BY
    VisitNumber DESC

预期输出:这是我期望的输出。我只想要TimeInRoom(不包括时间中的日期字段):

+------------+-------+-------------+-------------+---------+------------+
| CustomerID | Area  | VisitNumber | CurrentRoom | NewRoom | TimeInRoom |
+------------+-------+-------------+-------------+---------+------------+
|C33333333   |Area2  | 333333333   |             | BB4     | 00:10      |
|C33333333   |Area2  | 333333333   |             | POD8    | 00:20      |
|C33333333   |Area2  | 333333333   | POD8        |         | 00:30      |
+------------+-------+-------------+-------------+---------+------------+

【问题讨论】:

  • 这是一个关于如何提出一个好的 sql 问题的主要示例。 +1。
  • 除了列不匹配...
  • @iamrichhowell:您确定您的样本数据与您的描述一致吗?
  • 你怎么知道最后的退出时间?

标签: sql sql-server tsql sql-server-2012


【解决方案1】:

我希望这会有所帮助:

;WITH cte_Result AS
(
    SELECT
        [CustomerID],
        [Area],
        [VisitNumber],
        [CurrentRoom],
        [NewRoom],
        [Time],
        LAG([TIME]) OVER (partition by [CustomerID],[VisitNumber] ORDER BY ID DESC) PreviousTime,
        LEAD([TIME]) OVER (partition by [CustomerID],[VisitNumber] ORDER BY ID DESC) NextTime
    FROM #beds
    WHERE   [Area] = 'Area2'
        AND [CurrentRoom] IS NOT NULL
        AND [NewRoom] IS NOT NULL
        AND [CustomerID] IS NOT NULL
        AND [CustomerID] <> ' '
        AND [Event] IN (1,9)
        --AND [CustomerID] = 'C33333333'
),
cte_BuildStayPeriod
AS (
    SELECT CustomerID,
        Area,
        VisitNumber,
        CurrentRoom,
        NewRoom,
        DATEDIFF(SECOND, COALESCE([NextTime], PreviousTime), COALESCE(PreviousTime, [time])) AS StayDuration
    FROM cte_Result
)
SELECT CustomerID,
    Area,
    VisitNumber,
    CurrentRoom,
    NewRoom,
    StayDuration,
    CAST(DATEADD(SECOND, StayDuration, '1900-01-01') AS TIME) AS StayDuration
FROM cte_BuildStayPeriod

【讨论】:

  • 效果很好,非常感谢您的帮助。
【解决方案2】:

可能是我不太了解您的问题,但请尝试在您的 LAG / LEAD 函数中使用子句 PARTITION BY

,LAG(T1.TIME) OVER (PARTITION BY CustomerID ORDER BY T1.VisitNumber) PreviousTime
,LEAD(T1.TIME) OVER (PARTITION BY CustomerID ORDER BY T1.VisitNumber) NextTime

【讨论】:

    【解决方案3】:

    在您的示例中,当客户访问一次时,您将遇到问题,并且使用滞后/领先您将获得另一位客户的访问信息。

    试试看:

    SELECT
        T1.[User], T1.[CustomerID],
        T1.[Area], T1.[Event],
        T1.[VisitNumber],
        T1.[CurrentRoom], T1.[NewRoom],
        T1.[Time],
        (select TOP (1) t.Time from #beds t where t.[CustomerID] = T1.[CustomerID] and t.Time<T1.Time order by t.Time desc) PreviousTime,
        (select TOP (1) t.Time from #beds t where t.[CustomerID] = T1.[CustomerID] and t.Time>T1.Time order by t.Time) NextTime
    FROM
        #beds t1
    WHERE
        T1.[Area] = 'Area2'
        AND T1.[CurrentRoom] IS NOT NULL
        AND T1.[NewRoom] IS NOT NULL
        AND T1.[CustomerID] IS NOT NULL
        AND T1.[CustomerID] <> ' '
        AND T1.Event IN (1,9)
    ORDER BY
        VisitNumber DESC
    

    【讨论】:

      猜你喜欢
      • 2010-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-14
      • 2015-02-22
      相关资源
      最近更新 更多