简体   繁体   中英

Compare two records in a SQL Server table and delete unwanted records

I have this data in a table:

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

My question is: if there is a match on UID and ratecells are same for same UID with same dates but different codes, then delete records with codes 024. How can I write or join a query to achieve this?

I am thinking window functions:

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');

You can easily turn this into an actual delete if that is what you want.

Common table expression (CTE) is very helpful for the task. See example.

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

To build off what @Alex Kudryashev and @Gordon Linoff have answered this should delete the records that match on everything but Codes and also have a Codes values = to 024. This can be achieved by using a CTE to look for duplicates and then delete those duplicate records from the table.

    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'

The select statement returns this value

UID         Date                    Codes      Ratecell   RN
----------- ----------------------- ---------- ---------- ------
11111111    2017-01-01 00:00:00.000 024        A111       2

Then the select statement can be changed to delete this value

     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'

To paraphrase your edit... Where multiple rows share the same UID, date, ratecell values, but have different code values, delete all such rows WHERE code = '024'

WITH
    conflicts AS
(
    SELECT
        *,
        COUNT(DISTINCT code) OVER (PARTITION BY uid, [date], ratecell) AS potential_conflicts
    FROM
        yourTable
}
DELETE
    conflicts
WHERE
    potential_conflicts > 1
    AND code = '024'

Due to how the CTE is built, it's effectively schema bound which means that deleting a row from the CTE causes the underlying row in the source table to be deleted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM