如何从timestamp-sql总结几分钟内的UNIQUE总duarion

时间:2017-01-02 11:35:02

标签: postgresql timestamp postgresql-9.3

我有以下案例情景:

我的表有以下列:ID,ClientName(String),StartTime(时间戳),EndTime(时间戳)。

我的目标是为每个客户加上持续时间,例如对于最后一天,假设在一个时间段内可以是很少的值,我必须只有实际持续时间。

e.g。表内容:

|Client1    |   2017-01-01 08:00:00      |   2017-01-01 08:05:00|
|Client1    |   2017-01-01 08:00:00      |   2017-01-01 08:10:00|

我在这个例子中使用以下查询:

Select ClientName, SUM(date_trunc('second',coalesce(EndTime,now()::timestamp(0))-StartTime)) as duration 
from table 
group by ClientName

上述查询的结果为15,但应为10.同一时间段不应计算。

如何在PostgreSQL中获得正确的结果?

2 个答案:

答案 0 :(得分:0)

你没有提到你正在使用哪个数据库,每个数据库的实现都不同,但逻辑相同,

用于Postgresql 我使用row_number删除不正确的行

    select ClientName,
           SUM(date_trunc('second',coalesce(EndTime,now()::timestamp(0))-StartTime)) as duration,
           SUM(datediff(minute,StartTime,EndTIme)) as Duration2
    from(
    select ClientName,
           StartTime,
           EndTIme,
           row_number () over ( partition by ClientName,StartTime order by EndTime desc) as rank
    from table) a
    where rank=1
    group by ClientName

答案 1 :(得分:0)

请参考参考Calculate Actual Downtime ignoring overlap in dates/times

DECLARE @clientUsage TABLE (
    ID INT PRIMARY KEY NOT NULL IDENTITY(1,1),
    ClientName VARCHAR(25), 
    StartTime  DATETIME,
    EndTime  DATETIME
)

INSERT @clientUsage (ClientName, StartTime, EndTime) VALUES 
     ('client', '2014-11-20 17:31:01.467', '2014-11-20 18:01:01.243') 
    ,('client', '2014-11-28 17:59:00.987', '2014-11-28 18:09:02.167')
    ,('client', '2014-11-28 18:00:01.403', '2014-11-28 18:25:01.443') 
    ,('client', '2014-11-29 19:13:08.580', '2014-11-30 05:30:01.763') 
    ,('client', '2014-11-30 01:55:01.953', '2014-11-30 03:54:01.730')
    ,('client 2', '2014-12-19 23:09:01.303', '2014-12-22 09:43:01.397')
    ,('client 2', '2014-12-19 23:09:01.303', '2014-12-22 09:43:01.397')
    ,('client 2', '2014-12-19 23:09:01.303', '2014-12-22 09:43:01.397') 
    ,('client 2', '2014-12-19 23:09:01.303', '2014-12-22 09:43:01.397')
    ,('client 2', '2014-12-19 23:09:01.303', '2014-12-22 09:43:01.397') 

如果您使用表而不是临时表

select clientname,sum(actual) from
(SELECT
    clienttime.ClientName,
    clienttime.StartTime,
    clienttime.EndTime,
    COALESCE(Actual, 0) AS Actual
FROM @clientUsage clienttime
    LEFT OUTER JOIN (
        SELECT DISTINCT
            D1.ClientName,
            MIN(CASE WHEN D1.StartTime < D2.StartTime THEN D1.ID ELSE D2.ID END) AS [ID],
            MIN(CASE WHEN D1.StartTime < D2.StartTime THEN D1.StartTime ELSE D2.StartTime END) AS [StartTime],
            MAX(CASE WHEN D1.EndTime > D2.EndTime THEN D1.EndTime ELSE D2.EndTime END) AS [EndTime],
            DATEDIFF(MINUTE,
                MIN(CASE WHEN D1.StartTime < D2.StartTime THEN D1.StartTime ELSE D2.StartTime END),
                MAX(CASE WHEN D1.EndTime > D2.EndTime THEN D1.EndTime ELSE D2.EndTime END)) AS Actual
        FROM @clientUsage D1
            INNER JOIN @clientUsage D2
                ON D1.ClientName = D2.ClientName
                    AND (D1.StartTime BETWEEN D2.StartTime AND D2.EndTime
                        OR D2.StartTime BETWEEN D1.StartTime AND D1.EndTime)
        GROUP BY
            D1.ClientName,
            D1.StartTime
    ) Outages
        ON Outages.ID = clienttime.ID) op group by clientname

我在sql server中测试过。