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.