如何基于 SQL Server 中另一列的多个字符串更新列?

huangapple go评论74阅读模式
英文:

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

valueordinal 是由 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

演示链接如下:

演示1

演示2

英文:

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

Demo here

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

Demo here

答案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 如何基于 SQL Server 中另一列的多个字符串更新列?

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

huangapple
  • 本文由 发表于 2023年6月26日 21:52:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76557337.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定