sql - 相对于当前日期时间值按 +- 30 分钟分组
问题描述
我在表中有重复项,必须删除它们。
为什么?用户可以单击“保存”或“保存并关闭”按钮,由于错误,当他多次单击“保存”按钮时会出现记录克隆。典型的定位。
用户可以在表中添加重复项,但不经常每小时添加一个,会话时间约为 30 分钟。
换句话说 - 我们应该删除在 +- 30 分钟时间段内创建的记录。
我需要帮助,我可以在没有循环(光标)的情况下解决我的任务吗?
我的尝试和示例数据:
declare @testData table(id int, createdOn datetime, val varchar(20))
insert into @testData(id, createdOn, val)
select 1, '2018-06-01 14:00:00' as CreatedOn, 'value1' as value1
union select 2, '2018-06-01 14:02:00', 'value1' -- duplicate
union select 3, '2018-06-01 14:04:00', 'value1' -- duplicate
union select 4, '2018-06-01 15:00:00', 'value2'
union select 5, '2018-06-01 15:02:00', 'value2' -- duplicate
union select 6, '2018-06-01 15:03:00', 'valueUniq1'
union select 7, '2018-06-01 15:04:00', 'valueUniq2'
union select 8, '2018-06-01 15:40:00', 'value2'
union select 9, '2018-06-01 15:41:00', 'valueUniq3'
union select 10, '2018-06-01 15:59:00', 'value1' -- NOT DUPLICATE!!!
union select 11, '2018-06-01 16:05:00', 'value1' -- duplicate
-- Option 1
;
with duplicates(IdDup, CreatedOnDup, valueDup)
as (
select a.Id, a.CreatedOn, a.val
from @testData a, @testData b
where a.id <> b.id
and a.val = b.val
and a.CreatedOn between dateadd(minute, -30, b.CreatedOn) and dateadd(minute, 30, b.CreatedOn)
)
select * from @testData
where Id in (
select IdDup
from duplicates)
and Id not in (
select min(IdDup)
from duplicates
group by valueDup)
-- Option 2
;
with duplicates(CounterDup, IdDup)
as (
select ROW_NUMBER() OVER(
Partition By
a.val
, cast(a.CreatedOn as date) -- Incorrect, must be +- 30 minutes, not the whole day
Order By a.Id ASC) As counterDup
, a.Id as idDup
from @testData a, @testData b
where a.id <> b.id
and a.val = b.val
and a.CreatedOn between dateadd(minute, -30, b.CreatedOn) and dateadd(minute, 30, b.CreatedOn)
)
select * from @testData
where Id in (
select IdDup
from duplicates
where CounterDup > 1)
and Id not in (
select IdDup
from duplicates
where CounterDup = 1)
两种方法都返回相同的结果,要删除的行(重复):
2 2018-06-01 14:02:00.000 value1
3 2018-06-01 14:04:00.000 value1
5 2018-06-01 15:02:00.000 value2
10 2018-06-01 15:59:00.000 value1
11 2018-06-01 16:05:00.000 value1
倒数第二行不能在结果集中。
10 2018-06-01 15:59:00.000 value1
这不是重复的,它是一个新会话,因为在前一个“value1”之后 > 30 分钟。
解决方案
如果您想尝试没有延迟,您可以将此查询用于 SQL 的先前版本
Select * into #tmp from
(Select ROW_NUMBER() OVER(partition by val order by createdOn) valorder ,*
from @testData
) t
Select * from #tmp a
inner join #tmp b on a.id = (b.id + 1) and a.val = b.val
where DATEDIFF(mi, b.CreatedOn, a.CreatedOn) <=30
drop table #tmp;
推荐阅读
- c# - C#如何检查是否选中了任何datagridview复选框
- assembly - 警告:找不到入口符号_start;默认为 0000000008048060
- security - 我应该为 PWA + 服务器端应用程序使用哪个 OAuth2 身份验证流程
- bash - 默认返回的条件返回不起作用
- docker - Docker SSH 转发 - 绑定:地址不可用
- r - 在 r 中用 ggplot 绘制一个额外的独立列
- javascript - 无法从 Javascript 中的 API 捕获响应
- android - Android-将dp单位转换为因子0.5f的像素单位
- php - 如何使 API POST 调用请求的重定向与 HTML POST 请求完全相同
- hyperledger-fabric - Hyperledger Fabric 链码中的交易级共识/背书