SQL 根据日期和条件删除特定行

问题描述 投票:0回答:1

我有一个问题正在努力解决。我有一个表,其中有需要清理的重复数据。考虑以下示例:

CREATE TABLE #StackOverFlow
    ([ctrc_num] int, [Ctrc_name] varchar(6),[docu] bit, [adj] bit, new bit, [some_date] datetime)
;
    
INSERT INTO #StackOverFlow
    ([ctrc_num], [Ctrc_name],[docu],[adj],[new], [some_date])
VALUES
    (12345, 'John R',null,null,1,'2023-12-11 09:05:13.003'),
    (12345, 'John R',1,null,0, '2023-12-11 09:05:12.987'),
    (12345, 'John R',null,null,1, '2023-12-11 09:05:12.947'),
    (56789, 'Sam S',null,null,1, '2023-12-11 09:05:13.003'),
    (56789, 'Sam S',null,null,1, '2023-12-11 09:05:12.987'),
    (56789, 'Sam S',1,null,0, '2023-12-11 09:05:12.947'),
    (78945, 'Pat P',null,null,1, '2023-12-11 09:05:13.003'),
    (78945, 'Pat P',null,null,1, '2023-12-11 09:05:12.987'),
    (78945, 'Pat P',null,null,1, '2023-12-11 09:05:12.947')
;

这给了我:

[ctrc_num]  [Ctrc_name] [docu]  [adj]   [new]   [some_date]
12345        John R     NULL    NULL    1       2023-12-11 09:05:13.003
12345        John R     1       NULL    0       2023-12-11 09:05:12.987
12345        John R     NULL    NULL    1       2023-12-11 09:05:12.947
56789        Sam S      NULL    NULL    1       2023-12-11 09:05:13.003
56789        Sam S      NULL    NULL    1       2023-12-11 09:05:12.987
56789        Sam S      1       NULL    0       2023-12-11 09:05:12.947
78945        Pat P      NULL    NULL    1       2023-12-11 09:05:13.003
78945        Pat P      NULL    NULL    1       2023-12-11 09:05:12.987
78945        Pat P      NULL    NULL    1       2023-12-11 09:05:12.947

我需要做的是从表中删除重复项。如果 new 为 0,则删除 new 为 1 的记录。如果所有记录 new = 1,则保留最新记录并删除较旧的记录。

结果应该是这样的:

[ctrc_num]  [Ctrc_name] [docu]  [adj]  [new]    [some_date]
12345        John R     1       NULL    0       2023-12-11 09:05:12.987
56789        Sam S      1       NULL    0       2023-12-11 09:05:12.947
78945        Pat P      NULL    NULL    1       2023-12-11 09:05:13.003

我已尝试 ROW_NUMBER:

;WITH RankedByDate AS
(
SELECT ctrc_num
,Ctrc_name
,docu,adj,new
,some_date
,ROW_NUMBER() OVER(PARTITION BY Ctrc_num, Ctrc_name,[docu],[adj],[new] ORDER BY some_date DESC) AS rNum

FROM #StackOverFlow
)
select * from RankedByDate

这将 new = 0 的那些分开,但我仍然有已订购的 new = 1 的。

分组给了我重复的记录,但无法删除需要删除的记录:

SELECT [ctrc_num]
    ,[Ctrc_name]
    ,[docu]
    ,[adj]
    ,[new]
FROM #StackOverFlow
group by [ctrc_num]
    ,[Ctrc_name]
    ,[docu]
    ,[adj]
    ,[new]
having count(*)>1
sql sql-server t-sql sql-delete drop-duplicates
1个回答
0
投票

将问题分解为几个部分

  1. “如果new为0,则删除new为1的记录”

    从#StackOverFlow 中删除 其中 [new] = 1 和 [ctrc_num](从 #StackOverFlow 中选择 [ctrc_num],其中 [new] = 0);

  2. “如果所有记录都有新= 1,则保留最新记录并删除旧记录” 使用 CTE 根据日期添加行号并按 [ctrc_num] 分区,以便每个组中的“第一”记录是您要保留的记录 - 如果组中只有 1 行,那么这就是您要保留的记录无论如何都想保留。然后删除其他所有内容

    ;cte 为 ( 选择 [ctrc_num]
    ,ROW_NUMBER() OVER (PARTITION BY [ctrc_num] ORDER BY [ctrc_num], [some_date] DESC) as rw 来自#StackOverFlow ) 从 cte 中删除,其中 rw <> 1;

© www.soinside.com 2019 - 2024. All rights reserved.