如何在一列中拆分多行?

时间:2017-01-16 20:19:38

标签: sql sql-server-2012

我的数据集:

|-------|------|---------|-------|-------|-------|-------|
|OrderNo| Line |Customer | Desc  |Unit   |Price  | Amount|
|-------|------|---------|-------|-------|-------|-------|
|S123456|10    | John    | shirt | 1.00  | 19.99 | 0.00  |
|-------|------|---------|-------|-------|-------|-------|
|S123456|02    | John    | pants | 0.00  | 40.00 | 40.00 |
|-------|------|---------|-------|-------|-------|-------|
|S123777|01    | Jane    | misc  | 0.00  | 0.00  | 10.00 |
|-------|------|---------|-------|-------|-------|-------|
|S123777|02    | Jane    | pants | 0.00  | 40.00 | 40.00 |

试图实现的结果:

|-------|---------|------|------|------|-------|--------|------|------|------|-------|--------|
|OrderNo|Customer |Line1 |Desc1 |Unit1 |Price1 |Amount1 |Line2 |Desc 2|Unit2 |Price2 |Amount 2|
|-------|---------|------|------|------|-------|--------|------|------|------|-------|--------|
|S123456|John     |10    |shirt |1.00  |19.99  |0.00    |02    |pants |0.00  |40.00  |40.00   |
|-------|---------|------|------|------|-------|--------|------|------|------|-------|--------|
|S123777|Jane     |01    | misc |0.00  |0.00   |10.00   |02    |pants |0.00  |40.00  |40.00   |
|-------|---------|------|------|------|-------|--------|------|------|------|-------|--------|

关于数据

服务器: MSSQL Server 2012

数据类型:

[OrderNo] nvarchar NOT NULL

,[Line] [int] NOT NULL

,[Customer] nvarchar NOT NULL

,[n]非NOT NULL

,[Unit] [decimal](38,20)NOT NULL

,[Price] [decimal](38,20)NOT NULL

,[Amount] [decimal](38,20)NOT NULL

我希望每个OrderNo看到一行。试图查看每行订单中的所有行。

不幸的是,对于我需要提取的数据,行号不可靠(有时行03用于注释而不是实际项目),所以我不清楚如何获取第二行以拆分成所需的结果集。

任何帮助表示赞赏!!

1 个答案:

答案 0 :(得分:0)

假设你需要动态。只需将YourTable替换为您的实际表名。

Declare @SQL varchar(max) = 
Stuff((Select ','+QuoteName(concat('Line'  ,RN)) 
             +','+QuoteName(concat('Desc'  ,RN)) 
             +','+QuoteName(concat('Unit'  ,RN)) 
             +','+QuoteName(concat('Price' ,RN)) 
             +','+QuoteName(concat('Amount',RN)) 
        From (Select Distinct RN=Row_Number() over (Partition By OrderNo Order By Line) From YourTable) A  
        Order by 1 For XML Path('')),1,1,'') 

Select @SQL = '
Select [OrderNo],[Customer],' + @SQL + '
From (
        Select A.OrderNo
              ,A.Customer
              ,B.*
         From (Select *,RN = cast(Row_Number() over (Partition By OrderNo Order By Line) as varchar(25)) From YourTable) A
         Cross Apply (Values (''Line''  +A.RN,cast(A.[Line] as varchar(250)))
                            ,(''Desc''  +A.RN,cast(A.[Desc] as varchar(250))) 
                            ,(''Unit''  +A.RN,Format(A.[Unit]  ,''#,##0.00'')) 
                            ,(''Price'' +A.RN,Format(A.[Price] ,''#,##0.00'')) 
                            ,(''Amount''+A.RN,Format(A.[Amount],''#,##0.00'')) 
                      ) B (Item,Value)
     ) A
Pivot (max([Value]) For [Item] in (' + @SQL + ') ) p'
Exec(@SQL);

<强>返回

enter image description here

如果它有助于可视化,生成的SQL如下所示:

Select [OrderNo],[Customer],[Line1],[Desc1],[Unit1],[Price1],[Amount1],[Line2],[Desc2],[Unit2],[Price2],[Amount2]
From (
        Select A.OrderNo
              ,A.Customer
              ,B.*
         From (Select *,RN = cast(Row_Number() over (Partition By OrderNo Order By Line) as varchar(25)) From YourTable) A
         Cross Apply (Values ('Line'  +A.RN,cast(A.[Line] as varchar(250)))
                            ,('Desc'  +A.RN,cast(A.[Desc] as varchar(250))) 
                            ,('Unit'  +A.RN,Format(A.[Unit]  ,'#,##0.00')) 
                            ,('Price' +A.RN,Format(A.[Price] ,'#,##0.00')) 
                            ,('Amount'+A.RN,Format(A.[Amount],'#,##0.00')) 
                      ) B (Item,Value)
     ) A
Pivot (max([Value]) For [Item] in ([Line1],[Desc1],[Unit1],[Price1],[Amount1],[Line2],[Desc2],[Unit2],[Price2],[Amount2]) ) p

子查询生成此

enter image description here