Sql server SQL Server:使用OVER/Partition按分钟(或时间间隔)获取记录

Sql server SQL Server:使用OVER/Partition按分钟(或时间间隔)获取记录,sql-server,Sql Server,我正在尝试按记录运行的分钟对其进行分组。在下面的示例中,我有两个事件a01和a02。 我想得到以下信息 min 10:34 - a01 min 10:35 - a01 min 10:36 - a01 min 10:36 - a02 ... min 10:38 - a01 min 10:38 - a02 min 10:39 - a02 所以,我现在用一分钟作为时间间隔。你能给我举几个例子吗 在下面创建SQL: CREATE TABLE test_t1 ( t1 VARCHAR(150)

我正在尝试按记录运行的分钟对其进行分组。在下面的示例中,我有两个事件a01和a02。 我想得到以下信息

min 10:34 - a01
min 10:35 - a01
min 10:36 - a01
min 10:36 - a02
...
min 10:38 - a01
min 10:38 - a02
min 10:39 - a02
所以,我现在用一分钟作为时间间隔。你能给我举几个例子吗

在下面创建SQL:

CREATE TABLE test_t1 (
    t1 VARCHAR(150)
    ,StartTime DATETIME NULL
    ,EndTime DATETIME NULL
    );

INSERT INTO test_t1 (
    t1
    ,StartTime
    ,EndTime
    )
VALUES (
    'a01'
    ,convert(DATETIME, '20180101 10:34:09.630')
    ,convert(DATETIME, '20180101 10:38:09.630')
    );

INSERT INTO test_t1 (
    t1
    ,StartTime
    ,EndTime
    )
VALUES (
    'a02'
    ,convert(DATETIME, '20180101 10:36:09.630')
    ,convert(DATETIME, '20180101 10:39:09.630')
    );
你需要一个新的答案

DECLARE
    @minDateTime AS DATETIME,
    @maxDateTime AS DATETIME;

SELECT
    @minDateTime = MIN(StartTime),
    @maxDateTime = MAX(EndTime)
FROM test_t1;

DECLARE @Range AS INT = DATEDIFF(MINUTE, @minDateTime, @maxDateTime);

;WITH E1(N) AS( -- 10 ^ 1 = 10 rows
    SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N)
),
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b), -- 10 ^ 2 = 100 rows
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b), -- 10 ^ 4 = 10,000 rows
E8(N) AS(SELECT 1 FROM E4 a CROSS JOIN E4 b), -- 10 ^ 8 = 10,000,000 rows
CteTally(N) AS(
    SELECT TOP(@Range) ROW_NUMBER() OVER(ORDER BY(SELECT NULL))
    FROM E8
)
SELECT
    tt.t1,
    MinInterval = DATEADD(MINUTE, ct.N - 1, tt.StartTime)
FROM test_t1 tt
INNER JOIN CteTally ct
    ON DATEADD(MINUTE, ct.N - 1, tt.StartTime) <= tt.EndTime
ORDER BY
    tt.t1, MinInterval;
文章中的理货表查询简要说明:

递归CTE可以用来解决这类问题

with cte as (
    select 
        t1, StartTime = DATEADD(MINUTE, DATEDIFF(MINUTE, 0, StartTime), 0)
        , EndTime = DATEADD(MINUTE, DATEDIFF(MINUTE, 0, EndTime), 0)
    from 
        test_t1
)
, rcte as (
    select
        t1, StartTime, EndTime, convert(char(5), StartTime, 108) res
    from
        cte
    union all
    select
        t1, dateadd(mi, 1, StartTime), EndTime, convert(char(5), dateadd(mi, 1, StartTime), 108)
    from
        rcte
    where
        StartTime < EndTime
)

select
    t1, res
from
    rcte
order by t1

option (maxrecursion 0)