sqlserver:表中一列为分隔符分割的多个人名,添加一列存储每个人名的id用逗号分割

本文介绍了一种在SQLServer中将表中的咨询师姓名转换为其对应ID的方法,并使用逗号进行分隔。通过创建多个临时表进行数据处理,最终实现了姓名到ID的有效转换。

表中的数据是历史数据,ConsultorI列是人名的拼接,表中原本没有存储对应人名的id列ConsultorID,现添加一列ConsultorID,如图所示

11

对应的人名的id表是tblMember如图

11

现在问题来了,怎么用sqlserver把Consultor中存储的人名转换为对应的id,并用逗号分割存储到ConsultorID中呢?

因为sqlserver没有数组的概念

我的思路是:

 

--创建临时表放tblLatentStudent中的信息
CREATE TABLE #tb
    (
      SerialNo INT ,
      Consultor  VARCHAR(MAX) ,
      culomnsxml XML DEFAULT NULL
    )

--中间临时表存放SerialNo和切割后的Consultor字段
CREATE TABLE #temp
    (
      SerialNo INT ,
      Consultor VARCHAR(MAX) 
    )
--中间临时表存放tblMember表中咨询老师id和咨询老师名name
CREATE TABLE #result
    (
      id INT ,
      name VARCHAR(50) 
    )
    --最终表存放学生号SerialNo,和对应老师的名字Consultor和id (ConsultorID)
    CREATE TABLE #resultend
    (
     SerialNo INT ,
      Consultor VARCHAR(100) ,
      ConsultorID VARCHAR(50) 
    )
    
 insert into #tb(SerialNo,Consultor) select SerialNo,Consultor from tblLatentStudent



UPDATE  #tb
SET     culomnsxml = CONVERT(XML , '<root><v>' + REPLACE(a.Consultor , '/' , '</v><v>') + '</v></root>')
FROM    #tb a
SELECT SerialNo , Consultor,culomnsxml FROM #tb

INSERT  INTO #temp ( SerialNo , Consultor )
        SELECT  SerialNo , cx
        FROM    #tb a
                CROSS APPLY ( SELECT C.v.value ('.' , 'nvarchar(100)') cx FROM a.culomnsxml.nodes ('/root/v') C( v)
                            ) b   
--删除Consultor为空的行
DELETE FROM #temp WHERE Consultor=''
--插入表 tblMember的id和名字     
 INSERT  INTO #result ( id,name )
        (SELECT id,name
        FROM    tblMember   )  
         SELECT* FROM #result
INSERT  INTO #resultend ( SerialNo,Consultor,ConsultorID )(
        SELECT a.SerialNo,a.Consultor,b.id
        FROM    #temp a
    -- INNER   JOIN #result b ON a.Consultor=b.name
   LEFT JOIN #result b ON a.Consultor=b.name
   )
SELECT  *
FROM    #resultend  
DROP TABLE #tb
DROP TABLE #temp
DROP TABLE #result
DROP TABLE #resultend
<pre class="sql" name="code">SELECT * FROM	#resultend
declare @t table(SerialNo int,ConsultorID varchar(50))--定义结果集表变量   
--定义游标并进行合并处理  
 declare my_cursor cursor local for 
 select SerialNo , ConsultorID from #resultend  
 declare @id_old int , @id int , @value varchar(10) , @s varchar(100)  
 open my_cursor  
 fetch my_cursor into @id , @value  
 select @id_old = @id , @s=''  
 while @@FETCH_STATUS = 0  
begin  
  if @id = @id_old  
   select @s = @s + ',' + cast(@value as varchar)
     else  
        begin  
             insert @t values(@id_old , stuff(@s,1,1,''))  
     select @s = ',' + cast(@value as varchar) , @id_old = @id 
         end  
           fetch my_cursor into @id , @value  
         END  
         insert @t values(@id_old , stuff(@s,1,1,''))  
         close my_cursor  
         deallocate my_cursor  
          select * from @t 
UPDATE dbo.tblLatentStudent SET ConsultorID=a.a2
FROM (SELECT SerialNo AS a1 ,ConsultorID AS a2 FROM @t)AS a
WHERE dbo.tblLatentStudent.SerialNo=a.a1
SELECT ConsultorID,Consultor,* FROM tblLatentStudent 
          drop table #resultend 



 

 

 

 

 

<think>嗯,用户问的是在SQL Server中如何将一个用分号分割字段拆分成多行。我需要先回想下SQL Server中有没有内置的函数来处理字符串分割。记得在SQL Server 2016及以上版本,有个STRING_SPLIT函数,不过默认是按逗号分割的。但用户用的是分号,所以可能需要指定分隔符。不过STRING_SPLIT是否支持指定分隔符呢?查下文档,哦,对的,从SQL Server 2016开始,STRING_SPLIT确实支持指定分隔符作为第三个参数,但需要开启兼容性级别130或更高。所以可能需要用CROSS APPLY结合STRING_SPLIT,并指定分隔符为分号。 不过如果用户的SQL Server版本比较低,比如2014或更早,STRING_SPLIT可能不可用。这时候可能需要用传统的XML方法或者自定义函数来分割字符串。比如用XML的方法,通过将分号替换成XML标签,然后解析节点值。或者写一个自定义的split函数,用WHILE循环逐切分字符串。 所以,回答的时候应该先考虑版本问题,然后给出不同版本的解决方案。首先检查是否支持STRING_SPLIT,如果支持的话,用CROSS APPLY加上STRING_SPLIT,并指定分隔符为分号。如果不支持,就用XML方法或者自定义函数。另外,要提醒用户注意数据中的特殊字符,比如如果分号后面有空格或者数据中包含XML特殊符号如<、>、&等,可能需要先清理数据或使用其他方法。 另外,还要考虑性能问题,如果数据量大的话,STRING_SPLIT可能效率更高,而XML方法可能在处理大量数据时较慢。同时,注意返回的结果中可能有空格,需要用TRIM函数处理下。比如在STRING_SPLIT中,value字段可能会有前后的空格,特别是如果原始数据的分号后面有空格的话,这时候需要TRIM(value)。 最后,给出示例代码,并分步骤解释,确保用户能理解每步的作用。可能还需要提到兼容性问题和版本要求,让用户根据自己的环境选择合适的方案。如果有必要,还可以给出自定义函数的例子,供旧版本用户使用。</think>在 SQL Server 中,将一个用分号 `;` 分割字段拆分为多行,可以使用以下两种方法: --- ### 方法 1:使用 `STRING_SPLIT` 函数(SQL Server 2016+) **适用场景**:SQL Server 2016 及以上版本,且兼容级别设置为 130+。 ```sql SELECT t.id, TRIM(value) AS split_value -- TRIM 用于清除前后空格 FROM your_table t CROSS APPLY STRING_SPLIT(t.split_column, ';') WHERE value <> ''; -- 可选:过滤空值 ``` **说明**: 1. `STRING_SPLIT` 是内置函数,按指定分隔符拆分字符串 2. `CROSS APPLY` 将拆分结果与原关联 3. `TRIM(value)` 可去除拆分后值的首尾空格 --- ### 方法 2:使用 XML 方法(兼容旧版本) **适用场景**:SQL Server 2005+ 所有版本。 ```sql SELECT t.id, Split.a.value('.', 'VARCHAR(100)') AS split_value FROM ( SELECT id, CAST('<x>' + REPLACE(split_column, ';', '</x><x>') + '</x>' AS XML) AS xml_column FROM your_table ) t CROSS APPLY xml_column.nodes('/x') AS Split(a) WHERE Split.a.value('.', 'VARCHAR(100)') <> ''; -- 可选:过滤空值 ``` **说明**: 1. 通过 `REPLACE` 将分号替换为 XML 标签 2. 使用 XML 解析方法提取节点值 3. 注意:原始数据中不能包含 XML 特殊字符(如 `<`, `>`, `&`) --- ### 关键点总结 1. **版本选择**: - 优先使用 `STRING_SPLIT`(需 SQL Server 2016+) - 旧版本选择 XML 方法 2. **性能优化**: - 大操作时建议添加过滤条件 `WHERE split_column LIKE '%;%'` 3. **数据清理**: - 推荐先用 `TRIM` 处理原始字段的空格问题 4. **空值处理**: - 可通过 `WHERE value <> ''` 过滤拆分后的空值 --- ### 示例数据验证 假设原始数据: | id | split_column | |----|----------------| | 1 | apple;banana | | 2 | ;pear;grape | 输出结果: | id | split_value | |----|-------------| | 1 | apple | | 1 | banana | | 2 | pear | | 2 | grape | --- 如果遇到特殊字符或性能问题,建议先对原始数据进行标准化清洗,或考虑使用临时分步处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值