Reputation: 1307
I'm looking to add unique values with constraint and with a default value of -1
to term
and oldestyear
:
ALTER TABLE live_mytable
ADD CONSTRAINT live_mytable_uq
UNIQUE (id,loan_type,coalesce(term,-1),coalesce(oldestyear, -1));
Because my goal is to be able to upsert -- insert if set doesn't exist and update the apr
column if there's a conflict (if set exists but apr
value is different):
INSERT INTO live_mytable(id, loan_type, apr, term, oldestyear)
SELECT id, loan_type, apr, term, oldestyear
FROM imp_mytable
ON CONFLICT (id,loan_type,term,oldestyear)
DO UPDATE SET
apr = excluded.apr;
The reason why I need a default value -1
is because unique doesn't recognize null values, and columns term
and oldestyear
can be null.
I'm new to PostgreSQL so I'm not sure if my approach is correct.
id |loan_type |apr |term|oldestyear|
---------|---------------|------|----|----------|
68459|auto new | 3.50| 48| |
68459|auto new | 3.50| 60| |
68459|auto new | 3.99| 72| |
68459|auto used | 3.24| 36| |
68459|auto used | 3.74| 48| |
68459|auto used | 3.74| 60| |
68459|auto used | 3.99| 72| |
10066|auto new | 2.99| 36| |
10066|auto new | 3.29| 48| |
My question is, how can I upsert from imp_mytable
to live_mytable
given that term
and oldestyear
can be null. And only update if apr
is different when the unique set matches.
Upvotes: 1
Views: 1674
Reputation: 247475
With your current data model you cannot, unless you do it the old way with a loop in PL/pgSQL that tries both INSERT
and UPDATE
until one of them succeeds.
Maybe you can use a value other than NULL to denote missing values in your columns, like -1. That would make it easy, and it might also simplify some of your queries.
Upvotes: 1