比较SQL Server表中的两条记录并删除不需要的记录

比较SQL Server表中的两条记录并删除不需要的记录,sql,sql-server,tsql,Sql,Sql Server,Tsql,我在表格中有这些数据: UID Date Codes Ratecell --------------------------------------- 11111111 01/01/17 021 A111 11111111 01/01/17 024 A111 22222222 01/01/17 021 A112 22222222 01/01/17 024 A111 33333333 01

我在表格中有这些数据:

UID         Date       Codes   Ratecell
---------------------------------------
11111111    01/01/17    021    A111
11111111    01/01/17    024    A111
22222222    01/01/17    021    A112
22222222    01/01/17    024    A111
33333333    01/01/18    001    A112
33333333    01/01/18    021    A112

我的问题是:如果UID上存在匹配项,并且相同日期但代码不同的UID的RateCell相同,则删除代码为024的记录。如何编写或加入查询以实现此目的?

我认为窗口功能:

select t.*
from (select t.*,
             min(ratecell) over (partition by uid, date, code) as min_ratecell,
             max(ratecell) over (partition by uid, date, code) as max_ratecell
      from t
     ) t
where not (min_ratecell <> max_ratecell and ratecell = 'A112');

如果需要,您可以轻松地将其转换为实际删除。

我认为窗口功能:

select t.*
from (select t.*,
             min(ratecell) over (partition by uid, date, code) as min_ratecell,
             max(ratecell) over (partition by uid, date, code) as max_ratecell
      from t
     ) t
where not (min_ratecell <> max_ratecell and ratecell = 'A112');

如果需要,您可以轻松地将其转换为实际删除。

公共表表达式CTE对该任务非常有用。参见示例

declare @tbl table(UID int, [Date] Date, Codes varchar(10), Ratecell varchar(10))
insert @tbl values
(11111111,    '01/01/17',    '021',    'A111'),
(11111111,    '01/01/17',    '024',    'A111'),
(22222222,    '01/01/17',    '021',    'A112'),
(22222222,    '01/01/17',    '024',    'A111'),
(33333333,    '01/01/18',    '001',    'A112'),
(33333333,    '01/01/18',    '021',    'A112')

;with cte as (
select *,
ROW_NUMBER() over (partition by uid,[date],ratecell order by codes) rn
from @tbl
)
--select * from cte -- uncomment for test
delete cte --comment for test
where rn > 1

select * from @tbl t

公共表表达式CTE对该任务非常有帮助。参见示例

declare @tbl table(UID int, [Date] Date, Codes varchar(10), Ratecell varchar(10))
insert @tbl values
(11111111,    '01/01/17',    '021',    'A111'),
(11111111,    '01/01/17',    '024',    'A111'),
(22222222,    '01/01/17',    '021',    'A112'),
(22222222,    '01/01/17',    '024',    'A111'),
(33333333,    '01/01/18',    '001',    'A112'),
(33333333,    '01/01/18',    '021',    'A112')

;with cte as (
select *,
ROW_NUMBER() over (partition by uid,[date],ratecell order by codes) rn
from @tbl
)
--select * from cte -- uncomment for test
delete cte --comment for test
where rn > 1

select * from @tbl t

为了建立@Alex Kudryashev和@Gordon Linoff回答的内容,应该删除除代码外所有匹配的记录,并且代码值=到024。这可以通过使用CTE查找重复记录,然后从表中删除这些重复记录来实现

    Create table ##temp (
    [UID] int, [Date] datetime, [Codes] varchar(10), [Ratecell] varchar(10)
    )
    insert into ##temp
    (
      [UID]
     ,[Date]
     ,[Codes]
     ,[Ratecell]
    )

    values
    (11111111,    '01/01/17',    '021',    'A111'),
    (11111111,    '01/01/17',    '024',    'A111'),
    (22222222,    '01/01/17',    '021',    'A112'),
    (22222222,    '01/01/17',    '024',    'A111'),
    (33333333,    '01/01/18',    '001',    'A112'),
    (33333333,    '01/01/18',    '021',    'A112')


     ;with cte_ratecell as
     (
     select 
      [UID]
     ,[Date]
     ,[Codes]
     ,[Ratecell]
     ,ROW_NUMBER() over (partition by [UID], [Ratecell], [Date] order by Codes) as RN
     from
     ##temp
     )

     select * from ##temp

     --Delete c
     select *
     from
     (
      select 
      [UID]
     ,[Date]
     ,[Codes]
     ,[Ratecell]
     ,ROW_NUMBER() over (partition by [UID], [Ratecell], [Date] order by Codes) as RN
     from ##temp) c
     where
     RN > 1 and [Codes] = '024'
select语句返回此值

UID         Date                    Codes      Ratecell   RN
----------- ----------------------- ---------- ---------- ------
11111111    2017-01-01 00:00:00.000 024        A111       2
     Delete c
     --select *
     from
     (
      select 
      [UID]
     ,[Date]
     ,[Codes]
     ,[Ratecell]
     ,ROW_NUMBER() over (partition by [UID], [Ratecell], [Date] order by Codes) as RN
     from ##temp) c
     where
     RN > 1 and [Codes] = '024'
然后可以更改select语句以删除此值

UID         Date                    Codes      Ratecell   RN
----------- ----------------------- ---------- ---------- ------
11111111    2017-01-01 00:00:00.000 024        A111       2
     Delete c
     --select *
     from
     (
      select 
      [UID]
     ,[Date]
     ,[Codes]
     ,[Ratecell]
     ,ROW_NUMBER() over (partition by [UID], [Ratecell], [Date] order by Codes) as RN
     from ##temp) c
     where
     RN > 1 and [Codes] = '024'

为了建立@Alex Kudryashev和@Gordon Linoff回答的内容,应该删除除代码外所有匹配的记录,并且代码值=到024。这可以通过使用CTE查找重复记录,然后从表中删除这些重复记录来实现

    Create table ##temp (
    [UID] int, [Date] datetime, [Codes] varchar(10), [Ratecell] varchar(10)
    )
    insert into ##temp
    (
      [UID]
     ,[Date]
     ,[Codes]
     ,[Ratecell]
    )

    values
    (11111111,    '01/01/17',    '021',    'A111'),
    (11111111,    '01/01/17',    '024',    'A111'),
    (22222222,    '01/01/17',    '021',    'A112'),
    (22222222,    '01/01/17',    '024',    'A111'),
    (33333333,    '01/01/18',    '001',    'A112'),
    (33333333,    '01/01/18',    '021',    'A112')


     ;with cte_ratecell as
     (
     select 
      [UID]
     ,[Date]
     ,[Codes]
     ,[Ratecell]
     ,ROW_NUMBER() over (partition by [UID], [Ratecell], [Date] order by Codes) as RN
     from
     ##temp
     )

     select * from ##temp

     --Delete c
     select *
     from
     (
      select 
      [UID]
     ,[Date]
     ,[Codes]
     ,[Ratecell]
     ,ROW_NUMBER() over (partition by [UID], [Ratecell], [Date] order by Codes) as RN
     from ##temp) c
     where
     RN > 1 and [Codes] = '024'
select语句返回此值

UID         Date                    Codes      Ratecell   RN
----------- ----------------------- ---------- ---------- ------
11111111    2017-01-01 00:00:00.000 024        A111       2
     Delete c
     --select *
     from
     (
      select 
      [UID]
     ,[Date]
     ,[Codes]
     ,[Ratecell]
     ,ROW_NUMBER() over (partition by [UID], [Ratecell], [Date] order by Codes) as RN
     from ##temp) c
     where
     RN > 1 and [Codes] = '024'
然后可以更改select语句以删除此值

UID         Date                    Codes      Ratecell   RN
----------- ----------------------- ---------- ---------- ------
11111111    2017-01-01 00:00:00.000 024        A111       2
     Delete c
     --select *
     from
     (
      select 
      [UID]
     ,[Date]
     ,[Codes]
     ,[Ratecell]
     ,ROW_NUMBER() over (partition by [UID], [Ratecell], [Date] order by Codes) as RN
     from ##temp) c
     where
     RN > 1 and [Codes] = '024'

要解释你的编辑。。。如果多行共享相同的UID、date、ratecell值,但具有不同的代码值,请删除代码为“024”的所有此类行


由于CTE是如何构建的,它实际上是模式绑定的,这意味着从CTE中删除一行会导致源表中的基础行被删除。

要解释您的编辑。。。如果多行共享相同的UID、date、ratecell值,但具有不同的代码值,请删除代码为“024”的所有此类行


由于CTE是如何构建的,它实际上是模式绑定的,这意味着从CTE中删除一行会导致源表中的基础行被删除。

Thank@Gordon。我刚刚编辑了我的问题。我需要匹配ratecells并删除代码为024的记录。您能帮忙吗?谢谢@Gordon。我刚刚编辑了我的问题。我需要匹配ratecells并删除codes=024的记录。您是否有机会提供帮助?提示使用适当的软件MySQL、Oracle、DB2等标记数据库问题是很有帮助的。。。和版本,例如sql-server-2014。语法和特性的差异通常会影响答案。。。和版本,例如sql-server-2014。语法和功能的差异通常会影响答案。请投票否决我的答案的人解释他们为什么投票否决我的答案?请投票否决我的答案的人解释他们为什么投票否决我的答案?