I have the following table
id | customerNumber | productId | dateTime | action |
---|---|---|---|---|
2 | 12 | NA | 2018-11-04 14:55:16.000000 | active |
1 | 12 | NA | 2018-11-03 13:51:08.000000 | active |
The problem I have is that every time an action is registered, a new insert with a new row is created which I don’t need. Over time this table fills up.
INSERT INTO db.table("customerNumber", "productId", "dateTime", "action")
VALUES (:customerNumber, :productId, (now() at time zone ('utc')), :action);
So what I want to instead is to write a new query that follows the following criteria:
- If the row does not exist, insert a new one.
- If a single row exists with the customer number, update the values.
- If multiple rows exists with the same
customerNumber
, then only the one with the latestdateTime
should be updated.
In the table above for example, the first row with id == 2 should be updated only.
I have done some searching and testing. Many seem to refer to using the conflict operation, but this will not work since customerNumber
is not unique here. How can I make this happen within a single query?
2
Answers
Here’s how you can structure your query:
To perform this operation within a single query, you can use the
SQL MERGE
statement.You can use the following query to solve the issue that you have:You can use CTE to solve the following query and the query is as follows:
The above query using the CTE expression will first attempt to update the first row with the matching
customerNumber
and the latestdateTime
.If a row is updated, it returns the updated row’s data.
If no row matches the criteria, it returns an empty result.
Lastly insert a new row only if the updatedvalues_row CTE returned no rows