如何计算联系人在此数据库中的任何可用状态中的持续时间?

时间:2014-07-01 03:15:06

标签: sql tsql sql-server-2012

鉴于以下表格:

CREATE TABLE [Contact]
(
    [Id] INTEGER NOT NULL,
    [Uri] CHARACTER VARYING(255) NOT NULL,
    [CreatedOn] DATETIMEOFFSET NOT NULL
);

CREATE TABLE [Availability]
(
    [Id] TINYINT NOT NULL,
    [Name] CHARACTER VARYING(255) NOT NULL,
    [CreatedOn] DATETIMEOFFSET NOT NULL
);

CREATE TABLE [ContactAvailability]
(
    [Id] BIGINT NOT NULL,
    [ContactId] INTEGER NOT NULL,
    [AvailabilityId] INTEGER NOT NULL,
    [CreatedOn] DATETIMEOFFSET NOT NULL
);

我正在尝试获取所有联系人的列表以及他们在当天的任何可用性中所处的持续时间。

ContactAvailability表最终会有以下记录:

(1, 1, 1, '01/01/2014 08:00:23.51 -07:00'),
(2, 1, 3, '01/01/2014 08:15:38.01 -07:00'),
(3, 1, 3, '01/01/2014 08:15:38.02 -07:00'),
(4, 2, 2, '01/01/2014 08:18:33.12 -07:00')

这些记录代表Contact从一个Availability到另一个Availability的过渡,以及从ContactAvailability的过渡。它本质上是一个间隔记录的运行状态。

查询我只针对特定用户提出查询,并且只获取当天的可用性列表,但它不会计算SELECT [Contact].[Uri] AS [ContactUri], [Availability].[Name] AS [AvailabilityName], [ContactAvailability].[CreatedOn] FROM [ContactAvailability] INNER JOIN [Contact] ON [Contact].[Id] = [ContactAvailability].[ContactId] INNER JOIN [Availability] ON [Availability].[Id] = [ContactAvailability].[AvailabilityId] WHERE [Contact].[Uri] = 'sip:contact@example.com' AND [ContactAvailability].[CreatedOn] >= '06/30/2014 00:00:00 -07:00' AND [ContactAvailability].[CreatedOn] < '07/01/2014 00:00:00 -07:00' 在任何{{1}}中的持续时间{ {1}}。我不知道从哪里开始。

这是查询:

{{1}}

1 个答案:

答案 0 :(得分:0)

您可以将窗口功能与CTE结合使用。

我认为这应该可行,尚未测试:)所以你可能需要更改列名。

with SourceTable 
( ContactID, AvailabilityID, NewDate, OldDate)
as(
SELECT ContactAvailability.ContactID AS ContactID,
       ContactAvailability.AvailabilityID AS AvailabilityID,
       [ContactAvailability].[CreatedOn] As NewDate,
       LAG(ContactAvailability.CreatedON) OVER (Partition By ContactAvailability.ContactID order by ContactAvailability.CreatedOn) as OldDate

FROM [ContactAvailability])

SELECT [Contact].[Uri] AS [ContactUri],
       [Availability].[Name] AS [AvailabilityName],
       SourceTable.OldDate as PreviousAvailabilityDate,
       SourceTable.NewDate as CurrentAvailibilityDate,
       SourceTable.NewDate - SourceTable.OldDate as DifferenceBetweenAvailability,
       [ContactAvailability].[CreatedOn]
FROM SourceTable
INNER JOIN [Contact] ON [Contact].[Id] = SourceTable.[ContactId]
INNER JOIN [Availability] ON [Availability].[Id] = SourceTable.[AvailabilityId]

如果你需要计算一个人在某个可用性中的总时间(fe personA在可用性A中然后是B然后是A然后是C)你将不得不在ContactAvailability.AvailabilityID上添加另一个cte和分区然后make计算字段的总和。