使用自联接获取过去 1 小时的数据 T-SQL

Get past 1 hour data using a self join T-SQL

我有一个这样的 table (claimsTable),

 Time              Terminal_ID  Claims data_from
------------------------------------------------

2017-10-19 06:03:00     1        561     2
2017-10-19 06:04:00     1        562     2 
2017-10-19 06:05:00     1        562.3   2
2017-10-19 06:06:00     1        563     2
2017-10-19 06:03:00     9        471     2
2017-10-19 06:04:00     9        471.9   2
2017-10-19 06:05:00     9        472.3   2
2017-10-19 06:06:00     9        473     2
2017-10-19 06:07:00     1        567     1
2017-10-19 06:08:00     1        567.6   1 
2017-10-19 06:09:00     1        568.2   1
2017-10-19 06:10:00     1        569     1
2017-10-19 06:07:00     9        475     1
2017-10-19 06:08:00     9        475.9   1
2017-10-19 06:09:00     9        476.3   1
2017-10-19 06:10:00     9        476.3   1

每个 ID 都有数天的数据。我上面只展示了一些数据。现在,我检查来自 data_from = 1 的每个 Terminal_ID 的最旧数据,

select min(Time), Terminal_ID
from claimsTable 
where data_from = 1 
group by Terminal_ID

每个ID我得到2017-10-19 06:07:00

接下来,我像这样检查来自data_from =2的每个Terminal_ID的最新数据,

select max(Time), Terminal_ID 
from claimsTable 
where data_from = 2
group by Terminal_ID

现在,每个 Terminal_ID 我得到 2017-10-19 06:06:00

现在,我想从 data_from = 2 的最新时间(max(TIME))获取 60 分钟的数据,以计算来自 data_from = 1.

所以,我使用这样的自连接进行了检查,

select 
      t1.[Time], t1. Terminal_ID
from 
    claimsTable t1
inner join 
    claimsTable t2
    on t1.Terminal_ID = t2. Terminal_ID
where t1. Terminal_ID = t2. Terminal_ID and 
      t1.[Time] between dateadd(mi,-59,t2.[Time]) and t1.[Time]

这没有给我所需的检查,因为我没有对 t2t1 中的 min 函数使用 max 函数。当我进行自我加入时,我不确定如何包含它们。

我的预期输出 table:

Time              Terminal_ID  Claims data_from
------------------------------------------------
2017-10-19 06:03:00     1        561     2
2017-10-19 06:04:00     1        562     2 
2017-10-19 06:05:00     1        562.3   2
2017-10-19 06:06:00     1        563     2
2017-10-19 06:07:00     1        567     1
2017-10-19 06:03:00     9        471     2
2017-10-19 06:04:00     9        471.9   2
2017-10-19 06:05:00     9        472.3   2
2017-10-19 06:06:00     9        473     2
2017-10-19 06:07:00     9        475     1

如何从 data_from= 2 开始最旧的数据即 data_from = 1 开始检查前 60 分钟的数据?

只需在自连接的时间列上使用 max 函数即可。

select 
      max(t2.[Time]), 
      t1.Terminal_ID
from 
    claimsTable t1
full join 
    claimsTable t2
    on t1.Terminal_ID = t2. Terminal_ID
    and t2.time <= dateadd(mi,-59,t1.[Time]) 
group by
    t1. Terminal_ID

我试图计算 mintime(data_from = 1 )(Max - 60 mins AND data_from == 2)

之间所有记录的 Avg

问题是我在这两种情况下都得到 NULL 可能是因为查询中缺少某些内容 - 或者数据不足

尝试 运行 查询,如果有任何问题请告诉我。

这是创建示例数据的查询:

    -- CREATE SAMPLE DATA
    DROP TABLE #claimsTable

    CREATE TABLE #claimsTable
    (
        [Time] DateTime,
        Terminal_ID INT,
        Claims FLOAT,
        data_from INT

    )

    INSERT INTO #claimsTable
    VALUES

        (N'2017-10-19 06:03:00',     1 ,       561  ,   2),
        (N'2017-10-19 06:04:00',     1 ,       562  ,   2), 
        (N'2017-10-19 06:05:00',     1 ,       562.3,   2),
        (N'2017-10-19 06:06:00',     1 ,       563  ,   2),
        (N'2017-10-19 06:03:00',     9 ,       471  ,   2),
        (N'2017-10-19 06:04:00',     9 ,       471.9,   2),
        (N'2017-10-19 06:05:00',     9 ,       472.3,   2),
        (N'2017-10-19 06:09:00',     9 ,       473  ,   2),
        (N'2017-10-19 06:07:00',     1 ,       567  ,   1),
        (N'2017-10-19 06:08:00',     1 ,       567.6,   1), 
        (N'2017-10-19 06:09:00',     1 ,       568.2,   1),
        (N'2017-10-19 06:10:00',     1 ,       569  ,   1),
        (N'2017-10-19 06:05:00',     9 ,       475  ,   1),
        (N'2017-10-19 06:08:00',     9 ,       475.9,   1),
        (N'2017-10-19 06:09:00',     9 ,       476.3,   1)

我更改了 1 或 2 次示例数据以更好地了解我的查询生成的结果

实际查询从这里开始:

    Select
        A.TerminalId,
        Avrg = AVG(data_between.Claims)
    From
        (
        -- this inner query returns
        /*
            TerminalId  |           MaxTime (data_from == 2)    |   Min Time (data_from == 1)
            -------------------------------------------------------------------------------------
            9           |   2017-10-19 06:09:00.000             |   2017-10-19 06:05:00.000
            1           |   2017-10-19 06:06:00.000             |   2017-10-19 06:07:00.000
        */

            Select
                TerminalId = data_from_2.Terminal_ID,
                MaxTime2 = MAX(data_from_2.[Time]),
                MinTime1 = data_from_1.[Time]

            From
                #claimsTable data_from_2
                -- This will get MIN the data_from = 1 for each terminal_id
                CROSS APPLY (
                    SELECT TOP (1) 
                        * 
                    FROM #claimsTable  a

                    WHERE a.data_from = 1 AND a.Terminal_ID = data_from_2.Terminal_ID

                    ORDER BY a.[Time] ASC

                ) data_from_1
            --
            Where data_from_2.data_from = 2
            -- group by to get the Max.Time for each terminal
            GROUP BY data_from_2.Terminal_ID, data_from_1.[Time]
        ) A

        -- join with claimsTable again to get the data between mintime(data_from = 1 ) and (Max - 60 mins) so we can calculate avg

        LEFT JOIN #claimsTable data_between on data_between.Terminal_ID = A.TerminalId AND data_between.[Time] BETWEEN A.MinTime1 AND DATEADD(MINUTE, -60, A.MaxTime2)
        --
        GROUP BY A.TerminalId