如何计算SQL中具有相同值的连续变量的持续时间

时间:2015-05-20 05:10:30

标签: sql sql-server tsql

我有一张包含userlogdatecolor的表格。我想创建一个报告来计算每个颜色会话的查看持续时间。

Select 
t.user, t.url, datediff(mi,min(t.logdate),max(t.logdate)) as duration
from test as t
group by t.user, t.url
having duration > 0
order by logdate

问题是它将所有相同的URL分组到一个组中。

这是表格

user    logTime               color
-----  --------------------  ------
abc 1   2014-09-01 00:00:12.0 green     
abc 2   2014-09-01 00:00:13.5 green     
abc 3   2014-09-01 00:00:30.0 amber     
abc 4   2014-09-01 00:00:30.0 amber     
abc 5   2014-09-01 00:00:31.5 amber     
abc 6   2014-09-01 00:00:32.0 amber     
abc 7   2014-09-01 00:00:32.2 amber     
abc 8   2014-09-01 00:00:33.5 amber     
abc 9   2014-09-01 00:00:33.0   red     
abc 10  2014-09-01 00:00:35.0   red     
abc 11  2014-09-01 00:00:35.2   red     
abc 12  2014-09-01 00:00:37.0   red     
abc 13  2014-09-01 00:00:41.0   red     
abc 14  2014-09-01 00:00:42.0   red     
abc 15  2014-09-01 00:00:42.2   red     
abc 16  2014-09-01 00:00:43.0   red     
abc 17  2014-09-01 00:00:44.7   red     
abc 18  2014-09-01 00:00:44.2   red     
abc 19  2014-09-01 00:00:45.5   red     
abc 20  2014-09-01 00:00:47.0   red     
abc 21  2014-09-01 00:00:48.7   red     
abc 22  2014-09-01 00:00:49.7   red     
abc 23  2014-09-01 00:00:49.7   red     
abc 24  2014-09-01 00:00:49.9   red     
abc 25  2014-09-01 00:00:50.9 green     
abc 26  2014-09-01 00:00:50.0 green     
abc 27  2014-09-01 00:00:52.0 green     
abc 28  2014-09-01 00:00:53.0 green     
abc 29  2014-09-01 00:00:54.0 green     
abc 30  2014-09-01 00:00:55.0 green     
abc 31  2014-09-01 00:00:55.0 green     
abc 32  2014-09-01 00:01:02.0 green     
abc 33  2014-09-01 00:01:03.7 green     
abc 34  2014-09-01 00:01:05.7 green     
abc 35  2014-09-01 00:01:07.0 green     

3 个答案:

答案 0 :(得分:0)

您的问题不明确,因为您在查询中使用url但在示例数据中找不到它。

请注意,您可以将主要查询设为CTE,并根据您可以进行其他查询(您可以使用主表制作JOIN

示例表

DECLARE @tbl TABLE(url VARCHAR(10), [user] INT, logTime DATETIME2, color VARCHAR(10))

示例数据

INSERT @tbl
SELECT 'abc', 1  , '2014-09-01 00:00:12.0' , 'green' UNION ALL     
SELECT 'abc', 2  , '2014-09-01 00:00:13.5' , 'green' UNION ALL     
SELECT 'abc', 3  , '2014-09-01 00:00:30.0' , 'amber' UNION ALL     
SELECT 'abc', 4  , '2014-09-01 00:00:30.0' , 'amber' UNION ALL     
SELECT 'abc', 5  , '2014-09-01 00:00:31.5' , 'amber' UNION ALL     
SELECT 'abc', 6  , '2014-09-01 00:00:32.0' , 'amber' UNION ALL     
SELECT 'abc', 7  , '2014-09-01 00:00:32.2' , 'amber' UNION ALL     
SELECT 'abc', 8  , '2014-09-01 00:00:33.5' , 'amber' UNION ALL     
SELECT 'abc', 9  , '2014-09-01 00:00:33.0'   , 'red' UNION ALL     
SELECT 'abc', 10 , '2014-09-01 00:00:35.0'   , 'red' UNION ALL     
SELECT 'abc', 11 , '2014-09-01 00:00:35.2'   , 'red' UNION ALL     
SELECT 'abc', 12 , '2014-09-01 00:00:37.0'   , 'red' UNION ALL     
SELECT 'abc', 13 , '2014-09-01 00:00:41.0'   , 'red' UNION ALL     
SELECT 'abc', 14 , '2014-09-01 00:00:42.0'   , 'red' UNION ALL     
SELECT 'abc', 15 , '2014-09-01 00:00:42.2'   , 'red' UNION ALL     
SELECT 'abc', 16 , '2014-09-01 00:00:43.0'   , 'red' UNION ALL     
SELECT 'abc', 17 , '2014-09-01 00:00:44.7'   , 'red' UNION ALL     
SELECT 'abc', 18 , '2014-09-01 00:00:44.2'   , 'red' UNION ALL     
SELECT 'abc', 19 , '2014-09-01 00:00:45.5'   , 'red' UNION ALL     
SELECT 'abc', 20 , '2014-09-01 00:00:47.0'   , 'red' UNION ALL     
SELECT 'abc', 21 , '2014-09-01 00:00:48.7'   , 'red' UNION ALL     
SELECT 'abc', 22 , '2014-09-01 00:00:49.7'   , 'red' UNION ALL     
SELECT 'abc', 23 , '2014-09-01 00:00:49.7'   , 'red' UNION ALL     
SELECT 'abc', 24 , '2014-09-01 00:00:49.9'   , 'red' UNION ALL     
SELECT 'abc', 25 , '2014-09-01 00:00:50.9' , 'green' UNION ALL     
SELECT 'abc', 26 , '2014-09-01 00:00:50.0' , 'green' UNION ALL     
SELECT 'abc', 27 , '2014-09-01 00:00:52.0' , 'green' UNION ALL     
SELECT 'abc', 28 , '2014-09-01 00:00:53.0' , 'green' UNION ALL     
SELECT 'abc', 29 , '2014-09-01 00:00:54.0' , 'green' UNION ALL     
SELECT 'abc', 30 , '2014-09-01 00:00:55.0' , 'green' UNION ALL     
SELECT 'abc', 31 , '2014-09-01 00:00:55.0' , 'green' UNION ALL     
SELECT 'abc', 32 , '2014-09-01 00:01:02.0' , 'green' UNION ALL     
SELECT 'abc', 33 , '2014-09-01 00:01:03.7' , 'green' UNION ALL     
SELECT 'abc', 34 , '2014-09-01 00:01:05.7' , 'green' UNION ALL     
SELECT 'abc', 35 , '2014-09-01 00:01:07.0' , 'green' 

使用CTE

查询
;WITH C AS(
    SELECT color, DATEDIFF(MINUTE, MIN(logTime), MAX(logTime)) AS duration
    FROM @tbl
    GROUP BY color
)
SELECT * FROM C
WHERE duration > 0

答案 1 :(得分:0)

我认为你的问题是分组连续记录的经典SQL问题。您不能仅根据“颜色”列对记录进行分组。您需要为每个颜色会话生成某种会话索引。请尝试按照SQL执行此操作。这不是最终解决方案,但它会引导您获得理想的结果。这只是向您展示了如何组合具有相同颜色的连续记录并为它们建立会话索引的技术。一旦你有了会话索引,按它分组只是一个快照。一旦您的小组开始正常工作,会话持续时间将很容易得出。

DECLARE @MyTableVar table(
    username nvarchar(100) NOT NULL,
    logTime datetime,
    color nvarchar(10));


insert into @MyTableVar values('abc', '2014-09-01 00:00:12.0', 'green');
insert into @MyTableVar values('abc', '2014-09-01 00:00:18.0', 'green');
insert into @MyTableVar values('abc', '2014-09-01 00:00:25.0', 'amber');
insert into @MyTableVar values('abc', '2014-09-01 00:00:27.0', 'amber');
insert into @MyTableVar values('abc', '2014-09-01 00:00:35.0', 'red');
insert into @MyTableVar values('abc', '2014-09-01 00:00:38.0', 'green');
insert into @MyTableVar values('abc', '2014-09-01 00:00:41.0', 'green');

drop table #tmp;

select *, (ROW_NUMBER() OVER(ORDER BY logTime) - ROW_NUMBER() OVER(PARTITION BY color ORDER BY logTime)) As SessionIndex into #tmp from @MyTableVar order by logTime;

select SessionIndex, MAX(logTime) SessionStart, MIN(logTime) SessionEnd, DATEDIFF(SECOND, MIN(logTime), MAX(logTime)) AS SessionDurationSeconds from #tmp group by SessionIndex;

这是有详细信息的帖子。

http://sqlmag.com/sql-server/solution-t-sql-puzzle-grouping-consecutive-rows-common-element

答案 2 :(得分:0)

这可能是因为您没有在此处获得不准确的结果,只是最终日期的格式不正确。查阅特定类型的SQL(MySQL,SQL Server,...)的文档,了解如何将日期时间差异转换为整数,如分钟。