SQL Server 如何使用CTE标记记录

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

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程