I am trying to updated IDs in a table named Price, based on matches of IDs in a table named CW. Here is the SQL that I’m testing.
UPDATE Price SET ISN = (case when CW.id_cd = 'ISN' THEN CW.id_number else ISN end), SED = (case when CW.id_cd = 'SED' THEN CW.id_number else SED end), CSP = (case when CW.id_cd = 'CSP' THEN CW.id_number else CSP end) FROM CW WHERE Price.ID_GLOBAL = CW.asset_id
Here is a screen shot of the two schemas. So, now the values in the yellow cells are missing IDs, but I’m trying to get them filled in with the values I’m showing here.
The weird thing is that most of the IDs in the Price table are updated fine, based on the same IDs in the CW table, but not all IDs are being updated. After doing the above update, when I run the SQL below, I get a bunch of records returned, but I would expect no records at all because all CSP (IDs) should have been updated in the Price table.
Select * From Price INNER JOIN CW ON Price.id_global = CW.asset_id Where Price.CSP IS NUll AND CW.id_cd = 'CSP'
Advertisement
Answer
I think you have multiple rows in CW
for each ID_GLOBAL
. The problem is that only one matching row gets used. The solution is either a series of LEFT JOIN
s or pre-aggregation:
UPDATE Price SET ISN = COALESCE(cw.isn, price.isn), SED = COALESCE(cw.sed, price.sed), CSP = COALESCE(cw.csp, price.csp) FROM (SELECT asset_id, MAX(case when CW.id_cd = 'ISN' THEN CW.id_number END) as ISN, MAX(case when CW.id_cd = 'SED' THEN CW.id_number END) as SED, MAX(case when CW.id_cd = 'CSP' THEN CW.id_number END) as CSP FROM CW GROUP BY asset_id ) cw WHERE Price.ID_GLOBAL = CW.asset_id;
Note: This assumes that the new values are not ever NULL
. If that is a possibility, the assignment logic needs to take that into account. I am guessing that complication is unnecessary.
EDIT:
Do this in three steps. For 'ISN'
:
UPDATE Price SET ISN = cw.isn FROM CW WHERE Price.ID_GLOBAL = CW.asset_id AND CW.id_cd = 'ISN';
I am guessing the COALESCE()
is not necessary.