我想將行數據轉換爲列,其中列名不是來自數據。我認爲使用Pivot不會給我正確的解決方案。請參閱我的數據看起來像什麼和我希望它看起來的形象。使用SQL Server將行數據轉換爲列數據
的行數的例子返回將繼續隨時間增長。
我的解決辦法: 基於@Triv說,我已經使用管理rank函數來創建一個新列,然後使用動態SQL樞紐改造數據來解決問題。
我想將行數據轉換爲列,其中列名不是來自數據。我認爲使用Pivot不會給我正確的解決方案。請參閱我的數據看起來像什麼和我希望它看起來的形象。使用SQL Server將行數據轉換爲列數據
的行數的例子返回將繼續隨時間增長。
我的解決辦法: 基於@Triv說,我已經使用管理rank函數來創建一個新列,然後使用動態SQL樞紐改造數據來解決問題。
你可以使用動態sql + PIVOT
CREATE TABLE #SampleData
(
AccountNumber int,
Product varchar(20),
ProductEndDate datetime
)
INSERT INTO #SampleData VALUES (1,'Fixed 10','2016-01-01'),(1,'Fixed 11','2016-02-01'),(1,'Fixed 13','2016-03-01'),(1,'Fixed 12','2016-04-01'),
(2,'Fixed 10','2016-01-01'),(2,'Fixed 11','2016-02-01'),(2,'Fixed 13','2016-03-01')
DECLARE @HeaderAll nvarchar(max)
DECLARE @ColumnPivotProduct nvarchar(max)
DECLARE @ColumnPivotProductEndDate nvarchar(max)
;WITH temp AS
(
SELECT DISTINCT
CONCAT('Product' ,row_number() OVER(PARTITION BY sd.AccountNumber ORDER BY sd.Product)) AS ProductGroup,
CONCAT('ProductEndDate' ,row_number() OVER(PARTITION BY sd.AccountNumber ORDER BY sd.Product)) AS ProductEndDateGroup
FROM #SampleData sd
)
SELECT @HeaderAll = STUFF((SELECT CONCAT(',',t.ProductGroup,'= MAX(',t.ProductGroup, '),', t.ProductEndDateGroup ,'= MAX(', t.ProductEndDateGroup,')') FROM temp t FOR XML PATH('')), 1,1,''),
@ColumnPivotProduct = STUFF((SELECT CONCAT(',',t.ProductGroup) FROM temp t FOR XML PATH('')), 1,1,''),
@ColumnPivotProductEndDate = STUFF((SELECT CONCAT(',', t.ProductEndDateGroup) FROM temp t FOR XML PATH('')), 1,1,'')
--SELECT @HeaderAll, @ColumnPivotProduct, @ColumnPivotProductEndDate
DECLARE @query nvarchar(max) = CONCAT(
';WITH temp AS
(
SELECT *,
CONCAT(''Product'' ,row_number() OVER(PARTITION BY sd.AccountNumber ORDER BY sd.Product)) AS ProductGroup,
CONCAT(''ProductEndDate'' ,row_number() OVER(PARTITION BY sd.AccountNumber ORDER BY sd.Product)) AS ProductEndDateGroup
FROM #SampleData sd
)
SELECT AccountNumber, ',@HeaderAll,' FROM
(
SELECT t.AccountNumber, t.Product, t.ProductEndDate, t.ProductGroup,t.ProductEndDateGroup FROM temp t
) src
PIVOT
(
MIN(Product) FOR ProductGroup IN (',@ColumnPivotProduct,')
) pvt
PIVOT
(
MIN(ProductEndDate) FOR ProductEndDateGroup IN (',@ColumnPivotProductEndDate,')
) pvt1
GROUP BY AccountNumber
')
PRINT @query
exec(@query)
DROP TABLE #SampleData
演示鏈接:http://rextester.com/AEQBZ56634
注:CONCAT
是SQL服務器2012+繳費。如果您使用的是舊版本,然後使用+
爲串聯串
它的工作原理,檢查了這一點,而不是@testTable使用你的表名
declare @temptable varchar(1000) = 'declare @tempTable1 table (',
@inserStatement varchar(1000) = 'insert into @tempTable1 (',
@insertValues varchar(1000) = ''
DECLARE @AcountNumber VARCHAR(50),@Product varchar(40),@ProductEndData varchar(50), @increment int = 0;
DECLARE db_cursor CURSOR FOR
select
Product,
ProductEndData from @testTable
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @Product, @ProductEndData
WHILE @@FETCH_STATUS = 0
BEGIN
set @increment = @increment+1;
SET @temptable += 'Product'+ cast(@increment as varchar) +' varchar(100),' + 'Product' + cast(@increment as varchar) + 'EndDate varchar(100),' ;
set @inserStatement += 'Product'+ cast(@increment as varchar) +',' + 'Product' + cast(@increment as varchar) + 'EndDate,';
set @insertValues += '(''' + @Product +''''+ ',' + ''''+ @ProductEndData + '''' + ')';
FETCH NEXT FROM db_cursor INTO @Product, @ProductEndData
END
CLOSE db_cursor
DEALLOCATE db_cursor
set @temptable = STUFF(@temptable, LEN(@temptable), 1, ')')
set @inserStatement = STUFF(@inserStatement, LEN(@inserStatement), 1, ')')
set @insertValues = replace(@insertValues, ')(', ',')
exec (@temptable + @inserStatement + ' values ' + @insertValues + 'select * from @tempTable1')
我想你需要一個動態的SQL查詢。 – TriV
對不起,但我很新的SQL,不知道如何做到這一點。請你可以分享sql來做到這一點? – DDougill
你的sql服務器的版本? – TriV