Sql 如何将一个具有数组合并值的列拆分为数组,并连接另一个表,然后重新合并

Sql 如何将一个具有数组合并值的列拆分为数组,并连接另一个表,然后重新合并,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,有一张桌子是这样的: | BIL\_NO | USRS | DATE | | --- | --- | --- | | XC20090015 | ;STO09;STO02;STO04;STO06;STO10;STO07;STO10; | 2020\-09\-15 00:00:00.000 | | XC20090016 | ;STO09;STO02;STO04;STO06;STO10;STO07;STO10; | 2020\-09\-15 00:00:00.000 | | XC20090017 |

有一张桌子是这样的:

| BIL\_NO | USRS | DATE |
| --- | --- | --- |
| XC20090015 | ;STO09;STO02;STO04;STO06;STO10;STO07;STO10; | 2020\-09\-15 00:00:00.000 |
| XC20090016 | ;STO09;STO02;STO04;STO06;STO10;STO07;STO10; | 2020\-09\-15 00:00:00.000 |
| XC20090017 | ;STO09;STO02;STO04;STO06;STO10;STO07;STO10; | 2020\-09\-15 00:00:00.000 |
| XC20090018 | ;STO09;STO02;STO04;STO06;STO10;STO07;STO10; | 2020\-09\-16 00:00:00.000 |
和一个用户喜欢的表格:

| USR | NAME |
| --- | --- |
| STO02 | John |
| STO04 | Eva |
| STO06 | Lisa |
| STO07 | Boke |
| STO09 | Nii |
| STO10 | Alisa |

预期结果:

| BIL\_NO | USRS | DATE |
| --- | --- | --- |
| XC20090015 | ;Nii;John;Eva;Lisa;Alisa;Boke;Alisa; | 2020\-09\-15 00:00:00.000 |
| XC20090016 | ;Nii;John;Eva;Lisa;Alisa;Boke;Alisa; | 2020\-09\-15 00:00:00.000 |
| XC20090017 | ;Nii;John;Eva;Lisa;Alisa;Boke;Alisa; | 2020\-09\-15 00:00:00.000 |
| XC20090018 | ;Nii;John;Eva;Lisa;Alisa;Boke;Alisa; | 2020\-09\-16 00:00:00.000 |
我所尝试和思考的:

这是一个旧系统的表,因此我无法更改结构。
表逻辑是
select*from WaitCheckBil,其中usr类似“%”;+@usr+';%'以获取用户的等待检查票据编号

我认为它可以拆分
usrs列值转换为数组,然后在user列上与users表联接,然后合并回users列

但是我在这里遇到了麻烦,我不知道如何在
SQLServer2008
上实现逻辑


在线演示链接:

您应该能够同时使用STRING\u SPLIT和STRING\u AGG函数,类似这样的功能(我已将其添加到您的小提琴中):


哦,对不起。我看到你的小提琴是SQL Server 2017,并认为这是可以的。您需要SQL Server 2008吗?我看到STRING_SPLIT和STRING_AGG直到2016/2017版本才出现。您可能需要编写一个UDF,才能在SQL Server 2008中获得相同的结果。

您应该能够同时使用STRING\u SPLIT和STRING\u AGG函数,类似这样的函数(我已将其添加到您的小提琴中):


哦,对不起。我看到你的小提琴是SQL Server 2017,并认为这是可以的。您需要SQL Server 2008吗?我看到STRING_SPLIT和STRING_AGG直到2016/2017版本才出现。您可能需要编写一个UDF以在SQL Server 2008中获得相同的结果。

好的,下面是SQL Server 2008的UDF:

CREATE FUNCTION ufnReplaceUIDs(@inUIDs varchar(100))
RETURNS varchar(100)
AS   
--  Replace User Ids with User Names
BEGIN  
    DECLARE @UID varchar(10);
    DECLARE @outUNames varchar(100);  
    DECLARE @outUName varchar(10);
    DECLARE @String varchar(100);
    SET @String = SUBSTRING(@inUIDs, 2, LEN(@inUIDs) - 1)  -- Remove First/Last ; 
    WHILE (CHARINDEX(';', @String) > 0)
        BEGIN
            SET @UID = LEFT(@String, CHARINDEX(';', @String) - 1);
            SELECT @OutUName = [NAME] FROM Users WHERE [USR] = @UID; 
            SET @OutUNames = CONCAT(@OutUNames, ';', @OutUName); 
            SET @String = SUBSTRING(@String, CHARINDEX(';', @String) + 1, 100);
        END;
    RETURN CONCAT(@outUNames, ';');  
END; 
这样使用:
从WaitCheckBil
中选择[BIL_NO],dbo.ufnReplaceUIDs([USRS])作为[USRS],[DATE],结果是:


好的,下面是SQL Server 2008的自定义项:

CREATE FUNCTION ufnReplaceUIDs(@inUIDs varchar(100))
RETURNS varchar(100)
AS   
--  Replace User Ids with User Names
BEGIN  
    DECLARE @UID varchar(10);
    DECLARE @outUNames varchar(100);  
    DECLARE @outUName varchar(10);
    DECLARE @String varchar(100);
    SET @String = SUBSTRING(@inUIDs, 2, LEN(@inUIDs) - 1)  -- Remove First/Last ; 
    WHILE (CHARINDEX(';', @String) > 0)
        BEGIN
            SET @UID = LEFT(@String, CHARINDEX(';', @String) - 1);
            SELECT @OutUName = [NAME] FROM Users WHERE [USR] = @UID; 
            SET @OutUNames = CONCAT(@OutUNames, ';', @OutUName); 
            SET @String = SUBSTRING(@String, CHARINDEX(';', @String) + 1, 100);
        END;
    RETURN CONCAT(@outUNames, ';');  
END; 
这样使用:
从WaitCheckBil
中选择[BIL_NO],dbo.ufnReplaceUIDs([USRS])作为[USRS],[DATE],结果是:


谢谢,是的,我的问题是sql server 2008
。。。但是,如果没有新答案,您可以保留答案。我将接受它。您可以使用自定义项来执行此操作吗?谢谢,是的,我的问题在
sql server 2008
。。。但是如果没有新的答案,你可以保留答案。我会接受它。你能利用UDF来做这件事吗?