I have the following query to combine the columns into a comma-separated list (using this because STRING_AGG does not work for me probably due to an older version of SQL Server which I do not have control over):
SELECT TOP 1
STUFF((SELECT ',' t1.HAZARD_code_desc
FROM HAZARD_codes t1
WHERE mask & 67584 <> 0
FOR XML PATH('')), 1, LEN(','), '')
FROM
HAZARD_codes t0, sheldus51_copy sc
WHERE
t0.mask & 67584 <> 0
This is then used to update the value of column in another table using the following query:
UPDATE sheldus51_copy
SET hazard_type_combo = (SELECT TOP 1
STUFF((SELECT ',' t1.HAZARD_code_desc
FROM HAZARD_codes t1
WHERE mask & sc.mask <> 0
FOR XML PATH('')), 1, LEN(','), '')
FROM HAZARD_codes t0, sheldus51_copy sc
WHERE t0.mask & sc.mask <> 0)
However, the value of all the rows in the column hazard_type_combo are getting updated to the same value instead of being governed by the sc.mask value. i.e.
UPDATE table
SET column = (result of an expression)
this updates all rows to the same value. What am I missing here?
Some data below:
Query:
select distinct(mask)
from sheldus51_copy
Data:
196608
131072
32
65536
131104
2048
64
256
1
4
1024
128
16
32768
67584
2
4096
512
8
Query:
select HAZARD_code_desc, mask
from hazard_codes
Result:
Avalanche 1
Coastal 2
Drought 4
Earthquake 8
Flooding 16
Fog 32
Hail 64
Heat 128
Hurricane/Tropical Storm 256
Landslide 512
Lightning 1024
Severe Storm/Thunder Storm 2048
Tornado 4096
Tsunami/Seiche 8192
Volcano 16384
Wildfire 32768
Wind 65536
Winter Weather 131072
Example query
select HAZARD_code_desc, mask
from hazard_codes
where mask & 67584 <> 0
will match the rows where mask is 2048 and 65536 and therefore should set the value for hazard_type_combo to Severe Storm/Thunder Storm, Wind
CodePudding user response:
You need to reference and alias the sheldus51_copy table in a FROM clause at the top level, so that both the UPDATE and the nested select (correlated subquery) can reference the same rows. Try:
UPDATE sc
SET hazard_type_combo = STUFF((
SELECT ',' h.HAZARD_code_desc
FROM HAZARD_codes h
WHERE h.mask & sc.mask <> 0
-- ORDER BY ...
FOR XML PATH('')
), 1, LEN(','), '')
FROM sheldus51_copy sc
Suggest also adding an ORDER BY h.HAZARD_code_desc or ORDER BY h.mask if you want a predictable result.
And if sc.mask can ever be zero (no codes), you can add an ISNULL() around the expression to assign a default such as 'None' or the empty string.
