【问题标题】:Aggregating timeranges MSSQL聚合日期范围 SQL
【发布时间】:2018-09-02 00:07:01
【问题描述】:

给出下表显示计算机上的登录时间,如果有人可以帮助我编写一个 MS SQL 查询,它将提供表 2 中的聚合时间跨度,我将不胜感激:

表1(数据):

Usrkey  Username    DateTime_From           DateTime_To

1       Fox         2012-01-01 08:00    2012-01-01 08:15
1       Fox         2012-01-01 08:20    2012-01-01 08:25
2       Foxi        2012-01-01 09:30    2012-01-01 09:40
2       Foxi        2012-01-01 10:20    2012-01-01 10:25
1       Fox         2012-01-01 10:30    2012-01-01 10:35
1       Fox         2012-01-01 11:00    2012-01-01 11:40
2       Foxi        2012-01-01 12:50    2012-01-01 13:25
2       Foxi        2012-01-02 08:20    2012-01-02 08:25
2       Foxi        2012-01-02 09:20    2012-01-02 09:25
1       Fox         2012-01-02 11:30    2012-01-02 11:45
1       Fox         2012-01-02 12:50    2012-01-02 13:00
1       Fox         2012-01-02 13:20    2012-01-02 14:00

Table2(期望的结果):

Usrkey  Username    RangeFrom           RangeTo
1       Fox         2012-01-01 08:00    2012-01-01 08:25
2       Foxi        2012-01-01 09:30    2012-01-01 10:25
1       Fox         2012-01-02 10:30    2012-01-01 11:40
2       Foxi        2012-01-01 12:50    2012-01-02 09:25
1       Fox         2012-01-02 11:30    2012-01-02 14:00

【问题讨论】:

  • 到目前为止你尝试了什么?
  • 对我来说似乎是一个孤岛问题。有 1000 多个关于如何解决这些问题的答案。
  • 我尝试过使用窗口函数以及 LAG 和 LEAD 函数,但没有得到想要的结果。
  • 请把你试过的SQL贴出来。

标签: sql-server datetime aggregation window-functions


【解决方案1】:

OP 没有对他们的尝试做出回应,但我仍然建议他们这样做。这是一种不同的方法,使用ROW_NUMBER(),但是,如果您发布您尝试使用LEAD/LAG 的内容,那么我们也可以显示您在那里也出错了。

无论如何:

WITH VTE AS(
    SELECT Usrkey,
           Username,
           CONVERT(datetime2(0),DateTime_From) AS DateTime_From,
           CONVERT(datetime2(0),DateTime_To) AS DateTime_To
    FROM (VALUES (1,'Fox ','2012-01-01T08:00:00','2012-01-01T08:15:00'),
                 (1,'Fox ','2012-01-01T08:20:00','2012-01-01T08:25:00'),
                 (2,'Foxi','2012-01-01T09:30:00','2012-01-01T09:40:00'),
                 (2,'Foxi','2012-01-01T10:20:00','2012-01-01T10:25:00'),
                 (1,'Fox ','2012-01-01T10:30:00','2012-01-01T10:35:00'),
                 (1,'Fox ','2012-01-01T11:00:00','2012-01-01T11:40:00'),
                 (2,'Foxi','2012-01-01T12:50:00','2012-01-01T13:25:00'),
                 (2,'Foxi','2012-01-02T08:20:00','2012-01-02T08:25:00'),
                 (2,'Foxi','2012-01-02T09:20:00','2012-01-02T09:25:00'),
                 (1,'Fox ','2012-01-02T11:30:00','2012-01-02T11:45:00'),
                 (1,'Fox ','2012-01-02T12:50:00','2012-01-02T13:00:00'),
                 (1,'Fox ','2012-01-02T13:20:00','2012-01-02T14:00:00')) V(Usrkey,Username,DateTime_From,DateTime_To)),
Grps AS(
    SELECT Usrkey,
           Username,
           DateTime_From,
           DateTime_To,
           ROW_NUMBER() OVER (ORDER BY DateTime_From ASC) -
           ROW_NUMBER() OVER (PARTITION BY Usrkey ORDER BY DateTime_From ASC) AS Grp
    FROM VTE)
SELECT Usrkey, Username,
       MIN(DateTime_From) AS DateTime_From,
       MAX(DateTime_To) AS DateTime_To
FROM Grps
GROUP BY Usrkey, Username, Grp
ORDER BY DateTime_From ASC;

【讨论】:

  • 感谢大家的宝贵时间! Lamu,非常感谢您的快速回答和解决方案。我也尝试过使用 ROW_NUMBER(),但是您在 Grps CTE 中的 Grp 列是我的缺失点。再次感谢您。
  • @Hoira 就像我在答案中所说的那样,很高兴看到您之前尝试过的内容。此外,如果它对您有用,接受一个答案作为解决方案总是很好的。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-16
  • 2013-11-19
  • 1970-01-01
  • 1970-01-01
  • 2014-12-16
  • 2014-01-29
相关资源
最近更新 更多