英文:
How to update a column based on multiple string of another column in SQL Server?
问题
我尝试根据查找表中的英文内容来更新Multicode列,以下是表格:
#查找表
EN | ID |
---|---|
年度草地草 | 45 |
生长调节 | 828 |
叶子烫伤 | 971 |
杂草 - 阔叶 | 1997 |
#需要更新的表格
ResponseCode | EN | Multicode |
---|---|---|
6d5j87 | 年度草地草,杂草 - 阔叶 | NULL |
6d5j87 | 生长调节,叶子烫伤 | NULL |
6d5j87 | 叶子烫伤,杂草 - 阔叶 | NULL |
#预期表格输出
ResponseCode | EN | Multicode |
---|---|---|
6d5j87 | 年度草地草,杂草 - 阔叶 | 45,1997 |
6d5j87 | 生长调节 | 828 |
6d5j87 | 叶子烫伤,杂草 - 阔叶 | 971,1997 |
当前代码:
select EN, ID From #TargetFlatten1
select ResponseCode, EN, Multicode From #targettest
英文:
I have a table with two strings in a column. I am trying to update the multicode column based on the EN in Lookup table. Below are the tables:
#Lookup table
EN | ID |
---|---|
Annual meadow grass | 45 |
Growth regulation | 828 |
Leaf scald | 971 |
Weeds - Broadleaf | 1997 |
#Table that must be updated
ResponseCode | EN | Multicode |
---|---|---|
6d5j87 | Annual meadow grass,Weeds - Broadleaf | NULL |
6d5j87 | Growth regulation, Leaf scald | NULL |
6d5j87 | Leaf scald, Weeds - Broadleaf | NULL |
#Expected Table output
ResponseCode | EN | Multicode |
---|---|---|
6d5j87 | Annual meadow grass,Weeds - Broadleaf | 45,1997 |
6d5j87 | Growth regulation | 828 |
6d5j87 | Leaf scald, Weeds - Broadleaf | 971,1997 |
Current code:
select EN, ID From #TargetFlatten1
select ResponseCode, EN, Multicode From #targettest
答案1
得分: 1
一种选项是使用 string_split()
将 CSV 字符串转换为行,进行查找,然后使用 string_agg
聚合回代码:
select t.responseCode, t.en, x.multicode
from mytable t
cross apply (
select string_agg(l.responseCode) within group (order by ordinal) as multicode
from string_split(t.en, ',', 1)
inner join mylookup l on l.en = value
) x
value
和 ordinal
是由 string_split
生成的两列,分别存储 CSV 列表中的单个值及其在原始位置的值。
如果您需要进行更新,可以将逻辑转换为相关子查询:
update t
set t.multicode = (
select string_agg(l.responseCode) within group (order by ordinal)
from string_split(t.en, ',', 1)
inner join mylookup l on l.en = value
)
from mytable t
英文:
One option turns the CSV string to rows with string_split()
, does the lookup, then aggregates back the codes with string_agg
:
select t.responseCode, t.en, x.multicode
from mytable t
cross apply (
select string_agg(l.responseCode) within group (order by ordinal) as multicode
from string_split(t.en, ',', 1)
inner join mylookup l on l.en = value
) x
value
and ordinal
are two columns generated by string_split
wich store (resp) the single value and its original position in the CSV list.
If you wanted an update, we can turn the logic to a correlated subquery:
update t
set t.multicode = (
select string_agg(l.responseCode) within group (order by ordinal)
from string_split(t.en, ',', 1)
inner join mylookup l on l.en = value
)
from mytable t
答案2
得分: 1
以下是使用 SQL Server 2022 中的 STRING_SPLIT
函数进行操作的方法:
SELECT t2.ResponseCode, t2.EN, string_agg(ID, ',') WITHIN GROUP (ORDER BY ordinal)
FROM table2 t2
CROSS APPLY STRING_SPLIT(t2.EN, ',', 1) AS s
LEFT JOIN table1 t1 on t1.EN = TRIM(s.value)
GROUP BY t2.ResponseCode, t2.EN
更新语句如下:
UPDATE t
SET t.Multicode = s.Multicode
FROM table2 t
INNER JOIN (
SELECT t2.ResponseCode, t2.EN, string_agg(ID, ',') WITHIN GROUP (ORDER BY ordinal) AS Multicode
FROM table2 t2
CROSS APPLY STRING_SPLIT(t2.EN, ',', 1) AS s
LEFT JOIN table1 t1 on t1.EN = TRIM(s.value)
GROUP BY t2.ResponseCode, t2.EN
) AS S on s.ResponseCode = t.ResponseCode and s.EN = t.EN
对于 SQL SERVER 2017 和 2019,可以使用 OPENJSON
来保留序号:
SELECT t2.ResponseCode, t2.EN, string_agg(ID, ',') WITHIN GROUP (ORDER BY [key]) AS Multicode
FROM table2 t2
CROSS APPLY OPENJSON('["' + REPLACE(t2.EN, ',', '","') + '"]') AS s
LEFT JOIN table1 t1 on t1.EN = TRIM(s.value)
GROUP BY t2.ResponseCode, t2.EN
更新语句如下:
UPDATE t
SET t.Multicode = s.Multicode
FROM table2 t
INNER JOIN (
SELECT t2.ResponseCode, t2.EN, string_agg(ID, ',') WITHIN GROUP (ORDER BY [key]) AS Multicode
FROM table2 t2
CROSS APPLY OPENJSON('["' + REPLACE(t2.EN, ',', '","') + '"]') AS s
LEFT JOIN table1 t1 on t1.EN = TRIM(s.value)
GROUP BY t2.ResponseCode, t2.EN
) AS S on s.ResponseCode = t.ResponseCode and s.EN = t.EN
演示链接如下:
英文:
Here is a way to do it using STRING_SPLIT
with param 1 to enable ordinal (sql server 2022 ):
SELECT t2.ResponseCode, t2.EN, string_agg(ID, ',') WITHIN GROUP ( ORDER BY ordinal )
FROM table2 t2
CROSS APPLY STRING_SPLIT(t2.EN, ',', 1) AS s
LEFT JOIN table1 t1 on t1.EN = TRIM(s.value)
GROUP BY t2.ResponseCode, t2.EN
The update statement can be :
UPDATE t
SET t.Multicode = s.Multicode
FROM table2 t
INNER JOIN (
SELECT t2.ResponseCode, t2.EN, string_agg(ID, ',') WITHIN GROUP ( ORDER BY ordinal ) AS Multicode
FROM table2 t2
CROSS APPLY STRING_SPLIT(t2.EN, ',', 1) AS s
LEFT JOIN table1 t1 on t1.EN = TRIM(s.value)
GROUP BY t2.ResponseCode, t2.EN
) AS S on s.ResponseCode = t.ResponseCode and s.EN = t.EN
For SQL SERVER 2017 & 2019 we can use OPENJSON
to preserve ordinal :
SELECT t2.ResponseCode, t2.EN, string_agg(ID, ',') WITHIN GROUP ( ORDER BY [key] ) AS Multicode
FROM table2 t2
CROSS APPLY OPENJSON('["' + REPLACE(t2.EN,',','","') + '"]') AS s
LEFT JOIN table1 t1 on t1.EN = TRIM(s.value)
GROUP BY t2.ResponseCode, t2.EN
Update statement :
UPDATE t
SET t.Multicode = s.Multicode
FROM table2 t
INNER JOIN (
SELECT t2.ResponseCode, t2.EN, string_agg(ID, ',') WITHIN GROUP ( ORDER BY [key] ) AS Multicode
FROM table2 t2
CROSS APPLY OPENJSON('["' + REPLACE(t2.EN,',','","') + '"]') AS s
LEFT JOIN table1 t1 on t1.EN = TRIM(s.value)
GROUP BY t2.ResponseCode, t2.EN
) AS S on s.ResponseCode = t.ResponseCode and s.EN = t.EN
答案3
得分: 0
select
m.response_code
,m.en
,string_agg(l.id, ',') multicode
from
multicodes m
left join
lookup l on l.en in (select trim(value) from string_split(m.en, ','))
group by
m.response_code
,m.en
英文:
Assuming you are stuck with such a terrible schema, and assuming your data does have spaces in odd places like your example, and assuming you don't have any lookup values with comma's in them ... this should work in ms sql server - don't ask me about other flavors
select
m.response_code
,m.en
,string_agg(l.id, ',') multicode
from
multicodes m
left join
lookup l on l.en in (select trim(value) from string_split(m.en, ','))
group by
m.response_code
,m.en
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论