Sql-Get 时间范围从百万+行特定条件

Posted

技术标签:

【中文标题】Sql-Get 时间范围从百万+行特定条件【英文标题】:Sql-Get time ranges from million+ rows for particular condition 【发布时间】: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】:

我们可以在这里使用稍微修改的行号差异方法。第一个标记为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

【讨论】:

以上是关于Sql-Get 时间范围从百万+行特定条件的主要内容,如果未能解决你的问题,请参考以下文章

在R中有条件地计算特定数据范围的平均速度

获取特定范围/半径内的所有行(文档术语矩阵)

从具有特定日期范围的 SAS 数据集中删除行

具有特定条件计数的 Mongodb 聚合并按输出投影的日期范围过滤不能按预期工作

如何在特定层 Keras 上进行范围归一化

日单量从百万冲到千万,滴滴全链路压测实践!