【问题标题】:Sql-Get time ranges from million+ rows for particular conditionSql-Get 时间范围从百万+行特定条件
【发布时间】:2018-05-31 11:13:12
【问题描述】:

我正在使用 SQL Server 2012,我有一个大约 35 列和 10+ 百万行的表。 我需要从任何特定列的值匹配的数据中找到时间范围 例如。 样本数据如下

 Datetime        col1  col2  col3
2018-05-31 0:00     1   2   1 
2018-05-31 13:00    2   2   2
2018-05-31 14:30    3   2   1
2018-05-31 15:00    4   3   1
2018-05-31 16:00    4   5   1
2018-05-31 17:00    3   2   2
2018-05-31 17:30    3   2   4
2018-05-31 18:00    2   2   4
2018-05-31 20:00    1   2   6
2018-05-31 21:00    2   2   3
2018-05-31 21:10    2   2   1
2018-05-31 22:00    1   6   3
2018-05-31 22:00    4   5   1
2018-05-31 23:59    4   7   2

从 col2 值 =

Start Time           End time           Time Diff
2018-05-31 0:00     2018-05-31 14:30    14:30:00
2018-05-31 17:00    2018-05-31 21:10    4:10:00

我可以用下面的逻辑实现同样的效果,但是速度非常慢 我得到所有行,然后

  1. 按日期时间排序

  2. 扫描行获取与值完全匹配的第一行,并将该时间戳记录为开始时间。

  3. 进一步扫描行,直到我得到条件破坏的行并将该时间戳记录为结束时间。

但是因为我必须玩巨大的不。行中,总体而言,这将使我的操作变慢,任何输入或伪代码都可以改进。

【问题讨论】:

    标签: sql-server sql-server-2012 gaps-and-islands


    【解决方案1】:

    我们可以在这里使用稍微修改的行号差异方法。第一个标记为cte1 的 CTE 的目的是添加一个计算列,该列标记我们想要的岛,col2

    WITH cte1 AS (
        SELECT *,
            CASE WHEN col2 <= 2 THEN 1 ELSE 0 END AS class
        FROM yourTable
    ),
    cte2 AS (
        SELECT *,
            ROW_NUMBER() OVER (ORDER BY Datetime) -
            ROW_NUMBER() OVER (PARTITION BY class ORDER BY Datetime) rn
        FROM cte1
    )
    
    SELECT
        MIN(Datetime) AS [Start Time],
        MAX(Datetime) AS [End Time],
        CONVERT(TIME, MAX(Datetime) - MIN(Datetime)) AS [Time Diff]
    FROM cte2
    WHERE class = 1
    GROUP BY rn
    ORDER BY MIN(Datetime);
    

    Demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 2021-09-17
      • 1970-01-01
      相关资源
      最近更新 更多