为现有表创建连接列

问题描述 投票:0回答:2

我使用 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 个值。当子查询跟在 =, !=, <, <= , >, >= 或子查询用作表达式时,这是不允许的。

有没有办法让我更新这个新形成的表格列,使其显示如上所示?

sql sql-server sql-update alter-table
2个回答
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
   

0
投票

您的查询的问题是您的子查询没有正确链接到您要更新的单个记录,只要您的子查询返回多行。

为了解决这个问题,您可以尝试使用 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
© www.soinside.com 2019 - 2024. All rights reserved.