I have a table where the primary key is a composite key of ID and date. Is there a way that I can delete a single row where ID matches and the date is the latest date?
I am new to SQL, so I have tried a few things, but I either don't get the results I am looking for or cant get the syntax correct
DELETE FROM Master
WHERE ((Identifier = 'SomeID')
AND (EffectiveDate = MAX(EffectiveDate));
There are multiple columns with the same ID, but different dates, ie.
ID EffectiveDate
-------------------------
A '2019-09-18'
A '2019-09-17'
A '2019-09-16'
Is there a way I can delete only the row with A | '2019-09-18'?
You can use window functions and an updatable CTE:
with todelete as (
select t.*, row_number() over (partition by id order by effective_date desc) as seqnum
from t
)
delete from todelete
where seqnum = 1;
Note: If you want to limit this to a single id, then be sure to include a where id = 'a' in either the subquery or outer query.
use row_number()
delete from (select *, row_number() over(partition by id order by effectivedate desc) rn from table_name
) a where a.rn=1
A correlated subquery might get the job done:
DELETE FROM Master
WHERE
Identifier = 'SomeID'
AND EffectiveDate = (
SELECT MAX(EffectiveDate) FROM Master WHERE Identifier = 'SomeID'
)
;
Use the CTE Function to Delete the Row but the below Query will not delete the Record of Max Date of those ID's where Single Record exist against that.
with todelete as (
select t.*, row_number() over (partition by id order by effective_date desc) as seqnum
from t
)
delete from todelete
where seqnum = 1 and id in(select distinct id from todelete where seqnum<>1)
With correlated subquery for all IDs:
delete table1
from table1 t1
where t1.EffectiveDate =
(
select max(t2.EffectiveDate)
from table1 t2
where t2.ID = t1.ID
)
Related
The image below is an example of what my table looks like. I have duplicate rows, but a unique feature date_scanned. What I am trying to do is remove a single row by specifying the id, but when I do that all the rows with that id are removed and postgres does not let you use LIMIT after DELETE.
The below works when I remove WHERE id = 'F284', but will remove any row with rn =1. I need to specify the row id
DELETE FROM allergen_list WHERE date_scanned IN(
WITH cte AS (
SELECT date_scanned, row_number() OVER(PARTITION BY id, lot, expiration_date ORDER BY date_scanned DESC) as rn
FROM allergen_list WHERE id = 'F284'
)
SELECT date_scanned FROM cte WHERE rn = 1;
https://i.stack.imgur.com/Zf18E.png
Any help?
Why not just delete all rows where date is less than max?
DELETE FROM allergen_list
WHERE
id = 'F284' AND date_scanned < (
SELECT MAX(date_scanned)
FROM allergen_list WHERE id = 'F284'
)
I think Caius has the right approach. However, the logic would appear to be:
DELETE FROM allergen_list al
WHERE al.id = 'F284' AND
al.date_scanned < (SELECT MAX(al2.date_scanned)
FROM allergen_list al2
WHERE al2.id = al.id and al2.lot = al.lot and al2.expiration_date = al.expiration_date
);
I'm trying to delete duplicate rows from my table 'exchange_transactions' associated with the surgeon name 'Lucille Torres' using a cte. The transaction_id column should be unique but is duplicated in this case hence the attempt to delete them. I tried this code but it doesn't seem to work. Replacing 'DELETE' with 'SELECT *' shows me all the rows I want to delete. What am I doing wrong?
WITH cte AS (
SELECT
transaction_id,
surgeon,
ROW_NUMBER() OVER (
PARTITION BY
transaction_id
) row_num
FROM exchange_transactions)
DELETE FROM cte
WHERE surgeon = 'Lucille Torres' AND row_num > 1
Use the column ROWID to get the minimum value for each transaction_id that you will not delete:
delete from exchange_transactions
where surgeon = 'Lucille Torres'
and exists (
select 1 from exchange_transactions t
where t.surgeon = exchange_transactions.surgeon
and t.transaction_id = exchange_transactions.transaction_id
and t.rowid < exchange_transactions.rowid
)
Deleting directly from a CTE won't work in SqLite.
But if that table has a primary key (f.e. id)
then the result of the CTE can be used in the delete.
For example:
WITH CTE_DUPS AS
(
SELECT id,
ROW_NUMBER() OVER (
PARTITION BY surgeon, transaction_id
ORDER BY id) AS rn
FROM exchange_transactions
WHERE surgeon = 'Lucille Torres'
)
DELETE
FROM exchange_transactions
WHERE id IN (select id from CTE_DUPS where rn > 1)
Test on db<>fiddle here
I have to select CompanyId column only from the following SQL;
select CompanyId,
row_number() over (partition by [GradeName] order by [TankNumber] ) rn
from [Data_DB].[dbo].[Company] where CompanyCode='ASAAA'
In the SQL, I try to figure out duplicate records, and from another table i want to delete some records based on the CompanyId from above query.
that is;
delete from [[dbo].ObservationData
where CompanyId in (select CompanyId,
row_number() over (partition by [GradeName] order by [TankNumber] ) rn
from [Data_DB].[dbo].[Company] where CompanyCode='ASAAA')
How can I modify above query?
Assuming you don't care which duplicate gets retained or deleted, you may try using a deletable CTE here:
WITH cte AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY [GradeName] ORDER BY [TankNumber]) rn
FROM [Data_DB].[dbo].[Company]
WHERE CompanyCode = 'ASAAA'
)
DELETE
FROM cte
WHERE rn > 1;
This answer arbitrarily retains the "first" duplicate, with first being defined as the record with the earliest row number.
delete from [[dbo].ObservationData
where CompanyId in (select CompanyId from (select CompanyId,
row_number() over (partition by [GradeName] order by [TankNumber] ) rn
from [Datat_DB].[dbo].[Company] where CompanyCode='ASAAA') a where rn > 1 ;
I have the following query where the ID is not UNIQUE:
delete
( SELECT ROW_NUMBER() OVER (PARTITION BY createdOn, id order by updatedOn) as rn , id FROM `a.tab` ) as t
WHERE t.rn> 1;
The inner select return the result but the delete fails with:
Error: Syntax error: Unexpected "(" at [2:7]
What is the syntax problem here?
Unlike SQL Server, and a few other databases, Big Query does not allow deleting directly from a CTE. But, we can specify your target table, and then use the row number in the WHERE clause.
DELETE
FROM yourTable AS t1
WHERE (SELECT ROW_NUMBER() OVER (PARTITION BY createdOn, id ORDER BY updatedOn)
FROM yourTable AS t2
WHERE t1.id = t2.id) > 1;
The idea here is to correlate the row number value to each row in the delete statement using the id, which is presumably a primary key.
Use query as ::
delete from t
From ( SELECT ROW_NUMBER() OVER (PARTITION BY createdOn, id order by updatedOn) as rn , id FROM a.tab ) as t
WHERE t.rn> 1;
Hope this works
Here are the columns in my table:
Id
EmployeeId
IncidentRecordedById
DateOfIncident
Comments
TypeId
Description
IsAttenIncident
I would like to delete duplicate rows where EmployeeId, DateOfIncident, TypeId and Description are the same - just to clarify - I do want to keep one of them. I think I should be using the OVER clause with PARTITION, but I am not sure.
Thanks
If you want to keep one row of the duplicate-groups you can use ROW_NUMBER. In this example i keep the row with the lowest Id:
WITH CTE AS
(
SELECT rn = ROW_NUMBER()
OVER(
PARTITION BY employeeid, dateofincident, typeid, description
ORDER BY Id ASC), *
FROM dbo.TableName
)
DELETE FROM cte
WHERE rn > 1
use this query without using CTE....
delete a from
(select id,name,place, ROW_NUMBER() over (partition by id,name,place order by id) row_Count
from dup_table) a
where a.row_Count >1
You can use the following query. This has an assumption that you want to keep the latest row and delete the other duplicates.
DELETE [YourTable]
FROM [YourTable]
LEFT OUTER JOIN (
SELECT MAX(ID) as RowId
FROM [YourTable]
GROUP BY EmployeeId, DateOfIncident, TypeId, Description
) as KeepRows ON
[YourTable].ID = KeepRows.RowId
WHERE
KeepRows.RowId IS NULL