Reputation: 23
I want to do an UPDATE in Oracle SQL Developer and have following Code:
UPDATE DATABASE_1
SET COLOR = CASE WHEN COLOR IS NULL THEN '100'
WHEN COLOR = '100' THEN '100' ELSE COLOR END,
COLOR_UNIT = CASE WHEN COLOR_UNIT IS NULL THEN '%'
WHEN COLOR_UNIT = '' THEN '%'
WHEN COLOR_UNIT = ' ' THEN '%' ELSE COLOR_UNIT END
WHERE ID IN (SELECT t.ID
FROM DATABASE_1 t
JOIN DATABASE_2 s ON t.ID = s.ID AND t.SEQUENCE = s.SEQUENCE
WHERE s.CRITERIA = 'HIGH' AND t.SEQUENCE = (SELECT MAX (te.SEQUENCE) FROM DATABASE_1 te WHERE te.ID = s.ID));
When I run the SELECT
SELECT t.ID
FROM DATABASE_1 t
JOIN DATABASE_2 s ON t.ID = s.ID AND t.SEQUENCE = s.SEQUENCE
WHERE s.CRITERIA = 'HIGH' AND t.SEQUENCE = (SELECT MAX (te.SEQUENCE) FROM DATABASE_1 te WHERE te.ID = s.ID)
by itself, it gives me the correct result (as expected).
Thing is, once I run the whole UPDATE Statement, the AND t.SEQUENCE = (SELECT MAX (te.SEQUENCE) FROM DATABASE_1 te WHERE te.ID = s.ID)
part just gets ignored and it subsequently updates more rows (every entry which matches given ID and is true for s.CRITERIA = 'HIGH'
).
Upvotes: 1
Views: 412
Reputation: 23588
I'm not surprised that your query is matching to more rows than you're expecting - assuming you're only wanting to update the row with the latest sequence per id.
Your subquery is essentially doing a check that for each id, there's a row with a sequences that matches the max sequence value. That's always going to be true as long as there's at least one row for each id in the table!
Instead, what I think you're after is:
UPDATE DATABASE_1
SET COLOR = CASE WHEN COLOR IS NULL THEN '100'
WHEN COLOR = '100' THEN '100' ELSE COLOR END,
COLOR_UNIT = CASE WHEN COLOR_UNIT IS NULL THEN '%'
--WHEN COLOR_UNIT = '' THEN '%' -- totally irrelevant; there is no such thing as an empty string in Oracle (it is treated as NULL). Remove this.
WHEN COLOR_UNIT = ' ' THEN '%' ELSE COLOR_UNIT END
WHERE (ID, SEQUENCE) IN (SELECT t.ID, t.sequence
FROM DATABASE_1 t
JOIN DATABASE_2 s ON t.ID = s.ID AND t.SEQUENCE = s.SEQUENCE
WHERE s.CRITERIA = 'HIGH' AND t.SEQUENCE = (SELECT MAX (te.SEQUENCE) FROM DATABASE_1 te WHERE te.ID = s.ID));
Upvotes: 1