我使用 alter table 函数添加了列,但我现在正尝试使用“更新”和“设置”语法成功更新表并以所需格式转换数据
我基本上是想把它翻译成我可以用来更新表格的格式:
select record_no, string_agg(final_ip_description, ' | ') as Concatenated_IP
from [dm_na_fin_da].[updated_ip_dataset]
group by record_no
所需输出示例(按 record_no):
record_no Concatenated_IP
--------------------------------------------------
382102878 Transportation | Energy | Construction
当我尝试使用以下内容时,出现以下错误:
alter table [dm_na_fin_da].[ip_tiebreaker_ref_table]
add Concatenated_IP varchar(100);
update [dm_na_fin_da].[ip_tiebreaker_ref_table]
set Concatenated_IP = (select string_agg(final_ip_description, ' | ')
from [dm_na_fin_da].[updated_ip_dataset]
group by record_no)
错误
子查询返回超过 1 个值。当子查询跟在 =, !=, <, <= , >, >= 或子查询用作表达式时,这是不允许的。
有没有办法让我更新这个新形成的表格列,使其显示如上所示?
假设您想要使用每个
record_no
的所有IP的描述列表更新新列,那么,从您现有的查询开始,您需要correlate子查询到外部查询(并删除having
子句):
update r
set concatenated_ip = (
select string_agg(final_ip_description, ' | ')
within group (order by final_ip_description)
from ip_tiebreaker_ref_table r1
where r1.record_no = r.record_no -- correlation
)
from ip_tiebreaker_ref_table r
请注意,这会为具有相同
record_no
的所有行分配相同的值(within group
是为了使排序可预测)——这可能会被认为是数据重复——并且很难保持这些信息是最新的数据稍后更改。
另一种方法是使用视图,它可以让您以零维护成本始终了解最新的数据:
create view v_ip_tiebreaker_ref_table as
select r.*, r1.*
from ip_tiebreaker_ref_table r
cross apply (
select string_agg(final_ip_description, ' | ')
within group (order by final_ip_description) as concatenated_ip
from ip_tiebreaker_ref_table r1
where r1.record_no = r.record_no -- correlation
) r1
您的查询的问题是您的子查询没有正确链接到您要更新的单个记录,只要您的子查询返回多行。
为了解决这个问题,您可以尝试使用 SQL Server
FROM... WHERE
语句中的 UPDATE
子句。
UPDATE [dm_na_fin_da].[ip_tiebreaker_ref_table]
SET Concatenated_IP = cte.descr
FROM (SELECT record_no, STRING_AGG(final_ip_description, ' | ') AS descr
FROM [dm_na_fin_da].[updated_ip_dataset]
GROUP BY record_no) cte
WHERE [dm_na_fin_da].[ip_tiebreaker_ref_table].record_no = cte.record_no