使用动态 sql 旋转/取消旋转多个列

问题描述 投票:0回答:1

你们好,聪明的人们, 希望大家都一切顺利。

我有以下要求。

`CREATE TABLE #TempData 
(
    Columnname1 NVARCHAR(50),
    Value1 NVARCHAR(50),
    Columnname2 NVARCHAR(50),
    Value2 NVARCHAR(50),
    Columnname3 NVARCHAR(50),
    Value3 NVARCHAR(50)
);`

-- 将样本数据插入临时表

`INSERT INTO #TempData (Columnname1, Value1, Columnname2, Value2, Columnname3, Value3)
VALUES
('CustomerID', '1', 'CustomerName', 'A', 'CustomerCity', 'Hyd'),
('CustomerID', '2', 'CustomerName', 'B', 'CustomerCity', 'Mum'),
('CustomerID', '3', 'CustomerName', 'C', 'CustomerCity', 'Pune'),
('CustomerID', '4', 'CustomerName', 'D', 'CustomerCity', 'Nagpur'),
('CustomerID', '5', 'CustomerName', 'E', 'CustomerCity', 'Delhi'),
('CustomerID', '6', 'CustomerName', 'F', 'CustomerCity', 'Noida'),
('CustomerID', '1', 'CustomerDOB', 'July', NULL, NULL),
('CustomerID', '2', 'CustomerDOB', 'August', NULL, NULL),
('CustomerID', '3', 'CustomerDOB', 'September', NULL, NULL),
('CustomerID', '4', 'CustomerDOB', 'October', NULL, NULL),
('CustomerID', '5', 'CustomerDOB', 'November', NULL, NULL),
('CustomerID', '6', 'CustomerDOB', 'December', NULL, NULL);`
'
Above is just a sample. Apart from the columnname1, rest of the columns(Column name2,3 etc) can have multiple columns as shown in the columnname2. 
So I need to make sure that the result can look as below. 
Result set:
CustomerID  CustomerName    CustomerCity    CustomerDOB
1   A   Hyd July
2   B   Mum August
3   C   Pune    September
4   D   Nagpur  October
5   E   Delhi   November
6   F   Noida   December
`

所有这些都需要是动态的,因为列名不是静态的。它可能会因每个要求而异。您能否向我提供仅限 SQL Server 2014 中的动态 sql 来完成这项工作。

我尝试了以下方法。但无法使其立即对整个#temp 表起作用。

DECLARE @DynamicPivotQuery1 AS NVARCHAR(MAX)
DECLARE @DynamicPivotQuery2 AS NVARCHAR(MAX)
DECLARE @DynamicPivotQuery3 AS NVARCHAR(MAX)

DECLARE @ColumnName1 AS NVARCHAR(MAX)
DECLARE @ColumnName2 AS NVARCHAR(MAX)
DECLARE @ColumnName3 AS NVARCHAR(MAX)


-- Get distinct values of the PIVOT Column 
SELECT @ColumnName1 = ISNULL(@ColumnName1 + ',','') + QUOTENAME(Columnname1)
FROM (SELECT DISTINCT Columnname1 FROM #TempData) AS Columnnames

SELECT @ColumnName2 = ISNULL(@ColumnName2 + ',','') + QUOTENAME(Columnname2)
FROM (SELECT DISTINCT Columnname2 FROM #TempData) AS Columnnames

SELECT @ColumnName3 = ISNULL(@ColumnName3 + ',','') + QUOTENAME(Columnname3)
FROM (SELECT DISTINCT Columnname3 FROM #TempData) AS Columnnames

-- Create the dynamic PIVOT query
SET @DynamicPivotQuery1 = 
  N'SELECT DISTINCT ' + @ColumnName1 + ' 
    FROM 
    (
        SELECT Columnname1, Value1, Columnname2, Value2,Columnname3, Value3 
        FROM #TempData
    ) AS SourceTable
    PIVOT(MAX(Value1) 
          FOR Columnname1 IN (' + @ColumnName1 + ')) AS PivotedTable'

PRINT @DynamicPivotQuery1
EXEC sp_executesql @DynamicPivotQuery1

SET @DynamicPivotQuery2 = 
  N'SELECT ' + @ColumnName2 + '
    FROM 
    (
        SELECT Columnname1, Value1, Columnname2, Value2,Columnname3, Value3 
        FROM #TempData
    ) AS SourceTable
    PIVOT(MAX(Value2) 
          FOR Columnname2 IN (' + @ColumnName2 + ')) AS PivotedTable'

-- Execute the dynamic query
PRINT @DynamicPivotQuery2
EXEC sp_executesql @DynamicPivotQuery2

SET @DynamicPivotQuery3 = 
  N'SELECT ' + @ColumnName3 + '
    FROM 
    (
        SELECT Columnname1, Value1, Columnname2, Value2,Columnname3, Value3 
        FROM #TempData
        WHERE Columnname3 IS NOT NULL
    ) AS SourceTable
    PIVOT(MAX(Value3) 
          FOR Columnname3 IN (' + @ColumnName3 + ')) AS PivotedTable'
--MAX(CASE WHEN ColumnName1 = 'CustomerID' THEN Value1 END) as CustomerID
-- Execute the dynamic query
PRINT @DynamicPivotQuery3
EXEC sp_executesql @DynamicPivotQuery3
pivot sql-server-2014 dynamic-sql unpivot
1个回答
0
投票

假设Columnname1是固定的。首先使用

cross apply()
取消数据透视,然后使用
pivot
查询会更容易。

declare @cols nvarchar(max),
        @sql  nvarchar(max);

select @cols = isnull(@cols + ',', '') + quotename(Columnname)
from   #TempData
       cross apply
       (
           values
           (Columnname2), (Columnname3)
       ) c (Columnname)
group by Columnname


select @sql = N'select * '
            + N'from 
                (
                    select Value1 as CustomerID, Columnname, Columnvalue
                    from   #TempData
                           cross apply
                           (
                                values
                                (Columnname2, Value2),
                                (Columnname3, Value3)
                           ) c (Columnname, Columnvalue)
               ) d
               pivot
               (
                   max (Columnvalue)
                   for Columnname in (' + @cols + ')
               ) p'

print @sql

exec sp_executesql @sql


-- the dynamic query
select * 
from 
(
     select Value1 as CustomerID, Columnname, Columnvalue
     from   #TempData
            cross apply
            (
                values
                (Columnname2, Value2),
                (Columnname3, Value3)
            ) c (Columnname, Columnvalue)
 ) d
 pivot
 (
     max (Columnvalue)
     for Columnname in ([CustomerCity],[CustomerDOB],[CustomerName])
 ) p
© www.soinside.com 2019 - 2024. All rights reserved.