Reputation: 304
I have a table over which I have built an ETL service. Goods records (arrival / departure) go to the table. I have done that my table will be erased. When the item identifier arrives in the database for the second time, both records are deleted.
label cost time
x2 29 14/5/2020 01:00:00
x3 20 14/5/2020 01:02:00
x2 29 15/5/2020 03:12:02
Now ETL service remove records (every 30s):
label cost time
x3 20 14/5/2020 01:02:00
I delete it using the function:
with todelete as (
select *, count(*) over (partition by label) as cnt, ROW_NUMBER() over (partition by label order by time DESC) as r_number
from Table1
)
delete from todelete
where cnt >= 2
I just need to make a small change right now. When, for example, during those 30 seconds I get the second record in the table, but also the third that the goods have arrived again.
label cost time
x2 29 14/5/2020 01:00:00
x3 20 14/5/2020 01:02:00
x2 29 15/5/2020 03:12:02
x2 29 15/5/2020 03:12:22
In this case, I would lose the last record of the arrival of the goods. So I need to adjust the delete function. I've tried this, but it doesn't work properly.
with todelete as (
select *
, count(*) over (partition by label) as cnt
, ROW_NUMBER() over (partition by label order by time DESC) as r_number
from Table1
)
delete from todelete
where (cnt = 2 OR cnt = 4) OR (cnt = 3 AND r_number > 1);
Would anyone help me to modify that function please.
UPDATE: Exactly table: Step1:
label cost time
x2 29 14/5/2020 01:00:00
x3 20 14/5/2020 01:02:00
x2 29 15/5/2020 03:12:02
Step2: Delete row with function:
with todelete as (
select *, count(*) over (partition by label) as cnt, ROW_NUMBER() over (partition by label order by time DESC) as r_number
from Table1
)
delete from todelete
where cnt >= 2
My goal is described above, but one more thing that affects is when it comes to moving with a change in price like this:
label cost time
x2 29 14/5/2020 01:00:00
x3 20 14/5/2020 01:02:00
x2 30 15/5/2020 03:12:22
And then ETL deleted the old record and left the one with the new price.
label cost time
x3 20 14/5/2020 01:02:00
x2 30 15/5/2020 03:12:22
This fact complicates it even more.
Upvotes: 1
Views: 950
Reputation: 17126
why don't you try something like this.
Explanation:
Notice that I changed from DESC to ASC in the row_number() function's order by clause.
with this I delete the first arriving rows till the rows are even. if Cnt=3 then (cnt/2)*2=2 as cnt is integer(note integer/2 gives integer not a fraction)
when cnt=4 then (cnt/2)*2 gives back 4.
with todelete as (
select *, count(*) over (partition by label) as cnt, ROW_NUMBER() over (partition by label order by time ASC) as r_number
from Table1
)
delete from todelete
where cnt > 1 and r_number between 1 and (cnt/2)*2
Upvotes: 2