使用自联接获取过去 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]
这没有给我所需的检查,因为我没有对 t2
和 t1
中的 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
我有一个这样的 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]
这没有给我所需的检查,因为我没有对 t2
和 t1
中的 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