简体   繁体   中英

Delete from statement using aggregates in HAVING clause SQL Server 2008

I have a table that looks like the following 在此处输入图片说明

where what should be a unique identifier,drg, is not, so I started on the personal challenge of fixing it. I could do this easily a myriad of ways but I'm trying to do some things in a different fashion to learn some new techniques. What needs to be deleted from the table is any row whose drg is not unique and whose eff_date is **less than ** the max eff_date.

To find what I needed I used

select d1.drg, MAX(d1.eff_date) as maxEffDate,d2.drgdesc
    from drgtable d1
    inner join drgtable d2 on d1.drg=d2.drg 
    group by d1.drg,d2.drgdesc
    having MAX(d1.eff_date) = MAX(d2.eff_date)

Instead of just selecting this into a new table and dropping the old one, I'd like to do it in a delete statement.

My though process on the strange looking query below was to find the rows that weren't in the table from the above query I used and delete them. I got close, but am stuck. Also, if there's a way easier way to do this, please let me know. Thanks

--the purpose of this was to find the rows in d3 that were not in d4 and delete them. didn't quite get that far

delete from 
drgtable
where 
(
select * from drgtable as d3
left join 
(
select d1.drg, MAX(d1.eff_date) as maxEffDate,d2.drgdesc
    from drgtable d1
    inner join drgtable d2 on d1.drg=d2.drg 
    group by d1.drg,d2.drgdesc
    having MAX(d1.eff_date) = MAX(d2.eff_date)

) d4 on d4.drg =d3.drg and d4.maxEffDate = d3.eff_date and d3.drgdesc = d4.drgdesc
) 

This should work:

;WITH cte As
(
    SELECT  *,
            MAX(eff_date) OVER(partition by drg) as MaxEffDate
    FROM    drgtable
)
DELETE 
FROM    cte
WHERE   eff_date <> MaxEffDate

Plus, plenty of new tricks in there for you to learn. :-)

(note: this does assume that you are on SQL Server 2005 or higher)

If I understand your correct, you need smth like this?

delete drgtable 
from drgtable as d1
where exists
    (
        select t.*
        from drgtable as t where t.drg = d1.drg and t.eff_date > d1.eff_date
    )

Could you try:

delete from  drgtable 
where  DRG+MaxEffDate
not in
(Select drg+maxEffDate as Combo
FROM
  (select d1.drg, 
    MAX(d1.eff_date) as maxEffDate,
    d2.drgdesc     
    from drgtable d1     
    inner join drgtable d2 
    on d1.drg=d2.drg      
    group by d1.drg,d2.drgdesc     
    having MAX(d1.eff_date) = MAX(d2.eff_date) ) as RecordsToKeep
)
-- assuming there are no nulls in the data

? I realize this might be a bit hack-ish and there may be more eloquent solutions but this should work.

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