SQL Server 如何使用CTE标记记录
问题描述
我正在使用SQL Server,并且尝试使用CTE标记重复的记录。
基于Call_GUID、Call_Type_ID和Date相同而选择重复的记录。
我正在使用ROW_NUMBER函数对重复的记录进行分类。我想要标记除第一条记录之外的所有重复记录,根据”DateTime”列进行判断。
初始数据如下所示:
日期时间 | 通话类型ID | 通话GUID | 重复标志1 | 重复排名 |
---|---|---|---|---|
2023-09-21 09:28:01.370 | 12986 | 00A4AB00000100000000520883048B0A | NULL | 1 |
2023-09-21 09:35:08.270 | 12986 | 00A4AB00000100000000520883048B0A | NULL | 2 |
2023-09-21 09:35:29.887 | 12986 | 00A4AB00000100000000520883048B0A | NULL | 3 |
预期结果应该是这样的:
日期时间 | 呼叫类型ID | 呼叫GUID | 重复标志1 | 重复等级 |
---|---|---|---|---|
2023-09-21 09:28:01.370 | 12986 | 00A4AB00000100000000520883048B0A | 空 | 1 |
2023-09-21 09:35:08.270 | 12986 | 00A4AB00000100000000520883048B0A | Y | 2 |
2023-09-21 09:35:29.887 | 12986 | 00A4AB00000100000000520883048B0A | Y | 3 |
相反,我得到的是:
日期时间 | 呼叫类型ID | 呼叫GUID | 重复标志1 | 重复级别 |
---|---|---|---|---|
2023-09-21 09:28:01.370 | 12986 | 00A4AB00000100000000520883048B0A | 是 | 1 |
2023-09-21 09:35:08.270 | 12986 | 00A4AB00000100000000520883048B0A | 是 | 2 |
2023-09-21 09:35:29.887 | 12986 | 00A4AB00000100000000520883048B0A | 是 | 3 |
我正在使用下面的查询,但是”WHERE d.DupRank > 1″的条件没有被应用。
当我试图给子查询取一个别名(Dups)时,也出现了错误信息。
WITH Dups AS
(SELECT
"DateTime",
Call_Type_ID,
Call_GUID,
Dup_Flag1,
DupRank = ROW_NUMBER() OVER
(PARTITION BY Call_GUID, Call_Type_ID, "Date" ORDER BY "DateTime" ASC)
FROM #temp_records_SLS_U65_ALL
WHERE Call_GUID = '00A4AB00000100000000520883048B0A')
UPDATE #temp_records_SLS_U65_ALL
SET Dup_Flag1 = 'Y'
FROM #temp_records_SLS_U65_ALL AS t
INNER JOIN Dups AS d
ON t.Call_GUID = d.Call_GUID
WHERE d.DupRank > 1;
解决方案
你需要添加一些内容,使你的连接更具体。你只是在将你的临时表与dups
表连接,连接字段是Call_GUID
。你需要至少根据你在partition by
子句中使用的所有字段进行连接。
即便如此,在你的示例中,这还是不够的。
drop table if exists #table
create table #table
(
Dt datetime,
CallTypeId int,
CallGuid varchar(50),
DupFlag char(1)
)
insert into #Table
values
('2023-09-21 09:28:01.370', 12986, '00A4AB00000100000000520883048B0A', NULL),
('2023-09-21 09:35:08.270', 12986, '00A4AB00000100000000520883048B0A', NULL),
('2023-09-21 09:35:29.887', 12986, '00A4AB00000100000000520883048B0A', NULL)
考虑一下,这基本上是你运行以执行更新的查询:
;with dups as
(
select
Dt,
CallTypeId,
CallGuid,
DupFlag,
DupRank = row_number() over (partition by CallGuid, CallTypeId order by DT)
from #table
)
select *
from #Table t
inner join dups d
on t.CallGuid = d.CallGuid
--and t.CallTypeId = d.CallTypeID
--and t.Dt = d.Dt
where d.DupRank > 1
注意,当你最开始只有三行时,得到了六行。你在这里做的是向具有 CallTypeId 为 12986 和 CallGuid 为 00A4AB00000100000000520883048B0A 的每一行应用一个值为 “Y” 的值。那就是…全部。
你需要在其中添加其他字段(再次强调,至少包括其他分区列和在你的情况下,也包括日期时间字段)。
;with dups as
(
select
Dt,
CallTypeId,
CallGuid,
DupFlag,
DupRank = row_number() over (partition by CallGuid, CallTypeId order by DT)
from #table
)
select *
from #Table t
inner join dups d
on t.CallGuid = d.CallGuid
and t.CallTypeId = d.CallTypeID
and t.Dt = d.Dt
where d.DupRank > 1