【问题标题】:SQL query to split column data into rows将列数据拆分为行的 SQL 查询
【发布时间】:2012-11-23 10:50:05
【问题描述】:

我有 sql 表,因为我有 2 个字段,分别是 Nodeclaration

Code  Declaration
123   a1-2 nos, a2- 230 nos, a3 - 5nos

我需要将该代码的声明显示为:

Code  Declaration 
123   a1 - 2nos 
123   a2 - 230nos 
123   a3 - 5nos

我需要将列数据拆分为该代码的行。

【问题讨论】:

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


    【解决方案1】:

    对于这种类型的数据分离,我建议创建一个拆分函数:

    create FUNCTION [dbo].[Split](@String varchar(MAX), @Delimiter char(1))       
    returns @temptable TABLE (items varchar(MAX))       
    as       
    begin      
        declare @idx int       
        declare @slice varchar(8000)       
    
        select @idx = 1       
            if len(@String)<1 or @String is null  return       
    
        while @idx!= 0       
        begin       
            set @idx = charindex(@Delimiter,@String)       
            if @idx!=0       
                set @slice = left(@String,@idx - 1)       
            else       
                set @slice = @String       
    
            if(len(@slice)>0)  
                insert into @temptable(Items) values(@slice)       
    
            set @String = right(@String,len(@String) - @idx)       
            if len(@String) = 0 break       
        end   
    return 
    end;
    

    然后要在查询中使用它,您可以使用outer apply 来加入您现有的表:

    select t1.code, s.items declaration
    from yourtable t1
    outer apply dbo.split(t1.declaration, ',') s
    

    这将产生结果:

    | CODE |  DECLARATION |
    -----------------------
    |  123 |     a1-2 nos |
    |  123 |  a2- 230 nos |
    |  123 |    a3 - 5nos |
    

    SQL Fiddle with Demo

    或者你可以实现一个类似这样的 CTE 版本:

    ;with cte (code, DeclarationItem, Declaration) as
    (
      select Code,
        cast(left(Declaration, charindex(',',Declaration+',')-1) as varchar(50)) DeclarationItem,
             stuff(Declaration, 1, charindex(',',Declaration+','), '') Declaration
      from yourtable
      union all
      select code,
        cast(left(Declaration, charindex(',',Declaration+',')-1) as varchar(50)) DeclarationItem,
        stuff(Declaration, 1, charindex(',',Declaration+','), '') Declaration
      from cte
      where Declaration > ''
    ) 
    select code, DeclarationItem
    from cte
    

    【讨论】:

    • 乐于助人。如果此答案有帮助,请务必通过左侧的复选标记接受。它将帮助未来的访客,您将获得接受的声誉! :)
    • 由于您的帮助,我得到了代码声明 123 a1 - 2nos 123 a2 - 230nos 123 a3 - 5nos 123 a1 - 100nos 123 a3 - 6nos 的结果是否可以对重复项求和,我需要要显示的输出代码声明 123 a1 - 102nos 123 a2 - 230nos 123 a3 - 11nos
    • @Affan 我回答了你的另一个问题,提供了一个关于如何合计值的解决方案。
    • 请在这篇文章中指导我...stackoverflow.com/questions/15917099/…
    【解决方案2】:
    Declare @t Table([Code] int, [Declaration] varchar(32));    
    Insert Into @t([Code], [Declaration])
    Values(123, 'a1-2 nos, a2- 230 nos, a3 - 5nos')
    
    Select 
        x.[Code]
        ,t.Declaration  
        From
        (
            Select 
            *,
            Cast('<X>'+Replace(t.[Declaration],',','</X><X>')+'</X>' As XML) As record
    
            From @t t
        )x
        Cross Apply
        ( 
            Select fdata.D.value('.','varchar(50)') As Declaration 
            From x.record.nodes('X') As fdata(D)
        ) t
    

    几次回来,我也写过同样的博客Split Function in Sql Server using Set base approach

    另外,请访问 Erland Sommarskogblog,他在过去 15 年中一直保持着相同的答案。

    【讨论】:

      【解决方案3】:

      试试这个....

      declare @col1 varchar(100),@CurentSubString varchar(100)
      
      create table #temp
      (
          col1 varchar(50)
      )
      
      DECLARE CUR   CURSOR
      FOR     SELECT  col1
              FROM    your_table
      open    CUR
      
      FETCH   next 
      FROM    CUR
      INTO    @col1
      
      WHILE @@FETCH_STATUS = 0
      BEGIN
      
          WHILE   CHARINDEX (@col1, ';') <> 0
          BEGIN
          SET @CurentSubString    =   SUBSTRING(@col1,1,CHARINDEX (@col1, ';'))
          SET @col1 = SUBSTRING(@col1,CHARINDEX (@col1, ';')+1,len(@col1))
      
          insert into #temp
          select @CurentSubString
      END
      
      
      IF CHARINDEX (@col1, ';') = 0 and isnull(@col1,'')!= '' 
      BEGIN
          INSERT INTO #temp
          SELECT @col1
      END
      
      
      FETCH   next 
      FROM    CUR
      INTO    @col1
      
      END
      
      
      select  * 
      From    #temp
      
      CLOSE   CUR
      DEALLOCATE CUR
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-12-17
        • 1970-01-01
        • 2015-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-06
        相关资源
        最近更新 更多