【问题标题】:How to split one column with array merge value to array and join other table then merge back如何将具有数组合并值的一列拆分为数组并加入其他表然后合并回来
【发布时间】:2021-01-04 23:45:05
【问题描述】:

有一个像 WaitCheckBil 这样的表:

| 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 where usrs like '%;' + @usr + ';%';获取用户的等待校验bil_NO。

我认为它可以将 ; usrs 列值拆分为 array ,然后在 user 列上加入 users 表,然后合并回 users 列。

但是我在这里遇到了麻烦,我不知道如何在sql-server 2008上实现逻辑。

在线演示链接:SQL Server 2017 | db<>fiddle

【问题讨论】:

    标签: sql sql-server sql-server-2008


    【解决方案1】:

    好的,这是 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; 
    

    像这样使用它:SELECT [BIL_NO], dbo.ufnReplaceUIDs([USRS]) AS [USRS], [DATE] FROM WaitCheckBil,结果是:

    【讨论】:

      【解决方案2】:

      您应该能够一起使用 STRING_SPLIT 和 STRING_AGG 函数,就像这样(我已将它添加到您的小提琴中):

      WITH uSplit AS (
      SELECT [BIL_NO], [DATE], [USR], [NAME] FROM WaitCheckBil as wcb 
      OUTER APPLY STRING_SPLIT(SUBSTRING(wcb.[USRS], 2, LEN(wcb.usrs) - 2), ';') AS S
      LEFT JOIN Users AS U on U.[USR] = S.[value]
      )
      SELECT [BIL_NO], CONCAT(';', STRING_AGG([NAME], ';'), ';') AS [USRS], [DATE]
        FROM uSplit
       GROUP BY [BIL_NO], [DATE]
      

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

      【讨论】:

      • 谢谢,是的,我的麻烦在于sql-server 2008 ...但如果没有新的答案,您可以保留答案,我会接受。
      • 您能使用 UDF 来执行此操作吗?
      猜你喜欢
      • 2021-07-06
      • 2012-09-25
      • 1970-01-01
      • 1970-01-01
      • 2016-07-21
      • 1970-01-01
      • 1970-01-01
      • 2020-01-26
      • 2019-03-16
      相关资源
      最近更新 更多