【问题标题】:SQL Server split field and create addition rows with values from main rowSQL Server 拆分字段并使用主行中的值创建附加行
【发布时间】:2020-04-11 01:52:48
【问题描述】:

我有一个包含行的表,并且在一个字段中有这样的值 A、B、C

表'Mytable':

|ID | Date       | MyValue | SplitID |
|1  | 2019-12-17 | A       |         |
|2  | 2019-12-15 | A,B     |         |
|3  | 2019-12-16 | B,C     |         |

结果应该是:

|1 | 2019-12-17 | A | 1 |
|2 | 2019-12-15 | A | 2 |
|4 | 2019-12-15 | B | 2 |
|3 | 2019-12-16 | B | 3 |
|5 | 2019-12-16 | C | 3 |

(抱歉,我在 Stackoverflow 帮助中找不到如何格式化表格)

我尝试了一个内联表函数,它将字段 Myvalue 拆分为更多行,但无法使用

传递我的行
charindex(',',[MyValue])>0   

来自 MyTable 作为输入行。

代码是这样的:

ALTER function [dbo].[fncSplitString](@input Varchar(max), @Splitter Varchar(99), @ID int) 
returns table as
Return
with tmp (DataItem, ix, ID) as
( select LTRIM(@input)  , CHARINDEX('',@Input), @ID  --Recu. start, ignored val to get the types right
 union all
 select LTRIM(Substring(@input, ix+1,ix2-ix-1)), ix2, @ID
 from (Select *, CHARINDEX(@Splitter,@Input+@Splitter,ix+1) ix2 from tmp) x where ix2<>0
) select DataItem,ID from tmp where ix<>0

感谢您的帮助

迈克尔

【问题讨论】:

  • 您的 SQL Server 版本是多少?
  • 序数位置重要吗?
  • SQL Server 2012;没有序号位置不重要,我只需要在“SplitID”字段中添加“原始ID”即可跟进ID(PK)。
  • @Zhorov:你是如何格式化我的表格的???
  • 你可以用它来写漂亮的表格:senseful.github.io/text-table

标签: sql-server split


【解决方案1】:

我找到了这个解决方案,我希望它对你有用。但我没有使用你的功能来解决这个问题。 我使用了交叉应用功能。您可以在下面找到查询:

-- Creating Test Table

CREATE TABLE #Test
(
    ID int,
    Date date,
    MyValue nvarchar(max),
    SplitID int
);
GO

-- Inserting data into test table

INSERT INTO #Test VALUES (1, '2019-12-17', 'A', NULL);
INSERT INTO #Test VALUES (2, '2019-12-15', 'A,B', NULL);
INSERT INTO #Test VALUES (3, '2019-12-16', 'B,C', NULL);
GO

-- Select query

SELECT
*,
(SELECT ID FROM test t1 WHERE t.Date = t1.date) AS SplitID
FROM
(
SELECT 
    ROW_NUMBER() OVER (ORDER BY ID) AS ID,
    Date,
    substring(A.value,1,
    CASE WHEN charindex(',',rtrim(ltrim(A.value))) = 0 then LEN(A.value)
    ELSE charindex(',',rtrim(ltrim(A.value))) -1 end) as MyValue
FROM Test
CROSS APPLY string_split (MyValue, ',') A) AS T
ORDER BY MyValue ASC;

而且结果一定是这样的:

ID  Date        MyValue SplitID
1   2019-12-17  A       1
2   2019-12-15  A       2
3   2019-12-15  B       2
4   2019-12-16  B       3
5   2019-12-16  C       3

【讨论】:

    【解决方案2】:

    您可以尝试以下查询。

    Create table #Temp(
    Id int,
    DateField Date,
    MyValue Varchar(10),
    SplitID int
    )
    
    CREATE FUNCTION [dbo].[SplitPra] (@Value VARCHAR(MAX), @delimiter CHAR)  
    RETURNS @DataResult TABLE([Position] TINYINT IDENTITY(1,1),[Value] NVARCHAR(128))  
    AS  
    BEGIN  
    DECLARE @XML xml = N'<r><![CDATA[' + REPLACE(@Value, @delimiter, ']]></r><r><![CDATA[') + ']]></r>'  
    INSERT INTO @DataResult ([Value])  
    SELECT RTRIM(LTRIM(T.c.value('.', 'NVARCHAR(128)')))  
    FROM @xml.nodes('//r') T(c)  
    RETURN  
    END  
    
    insert into #Temp Values(1, '2019-12-17', 'A', NULL),(2, '2019-12-15', 'A,B', NULL), (3, '2019-12-16', 'B,C', NULL)
    
    Select 
        #Temp.Id, DateField, b.Value as MyValue, b.Id as SplitValue 
    from #Temp inner join (
    select 
        Id, f.* 
    from 
        #Temp u
        cross apply [dbo].[SplitPra](u.MyValue, ',') f   
    )b on #Temp.Id = b.Id
    
    Drop table #Temp
    

    这将给出如下所示的输出。

    Id  DateField   MyValue SplitValue
    ---------------------------------
    1   2019-12-17  A       1
    2   2019-12-15  A       2
    2   2019-12-15  B       2
    3   2019-12-16  B       3
    3   2019-12-16  C       3
    

    您可以找到现场演示here

    【讨论】:

      猜你喜欢
      • 2019-02-22
      • 1970-01-01
      • 1970-01-01
      • 2020-01-31
      • 2017-04-25
      • 2013-03-23
      • 2023-04-08
      • 2016-02-28
      • 1970-01-01
      相关资源
      最近更新 更多