WITH TAB AS ( SELECT id,flag FROM source where flag IS NULL and Data= '151234567890' ORDER BY 1 OFFSET ( SELECT COUNT(*) FROM source where flag IS NULL and Data = '151234567890' ) - 96 FETCH FIRST 96 ROWS ONLY ) UPDATE TAB SET flag = 'Z';
Above query is working fine in MS Sql but showing this error when running it in postgres
ERROR: relation "tab" does not exist LINE 9: UPDATE TAB SET flag = 'Z';
Advertisement
Answer
In MS Sql Server it’s possible to update the CTE.
In Postgresql you can link to a CTE for an update.
For example:
WITH CTE AS ( SELECT id FROM source WHERE Data= '151234567890' AND flag IS NULL ORDER BY id DESC FETCH FIRST 96 ROWS ONLY ) UPDATE source t SET flag = 'Z' FROM CTE c WHERE t.id = c.id;
However, such update assumes that the id in that table is unique.
But, to mark the newest duplicates it can be simplified.
UPDATE source tgt SET flag = 'Z' FROM source src WHERE src.Data = '151234567890' AND tgt.Data = src.Data AND tgt.id = src.id AND tgt.ctid > src.ctid AND tgt.flag IS NULL;
Or if you want to flag the higher amounts.
Using ROW_NUMBER could help.
WITH CTE AS ( SELECT ctid, id, Data, Amt , ROW_NUMBER() OVER (PARTITION BY Data, id ORDER BY Amt) AS rn FROM source WHERE Data= '151234567890' AND flag IS NULL ) UPDATE source t SET flag = 'Z' FROM CTE c WHERE c.rn > 1 AND t.id = c.id AND t.Data = c.Data AND t.ctid = c.ctid;
Test on db<>fiddle here