这是SQL Server的实际结果集
+-----------+--------+------------------+
| Dates | Orders | Cancelled Orders |
+-----------+--------+------------------+
|2016-01-17 | 100 | 50 |
|2016-01-18 | 120 | 20 |
|2016-01-20 | 150 | 30 |
+-----------+--------+------------------+
我需要转动表格,如下所示
+----------+------------+------------+------------+
|Dates | 2016-01-17 | 2016-01-18 | 2016-01-19 |
+----------+------------+------------+------------+
|Orders | 100 | 120 | 150 |
+----------+------------+------------+------------+
|Cancelled | | | |
|Orders | 50 | 20 | 30 |
+----------+------------+------------+------------+
任何人都可以在撰写查询时给我建议吗?这里的日期必须是动态的。
答案 0 :(得分:2)
试试这个查询......它会帮助你
select * into #tempp from(
select '2016-01-17' as DATES,100 ORDERS,50 CANCELED_ORDERS
UNION ALL
SELECT '2016-01-18',120,20
UNION ALL
SELECT '2016-01-20',150,30
)AS A
--SELECT * FROM #tempp
declare @pivotcols nvarchar(max),@unpivotcols nvarchar(max),@SQLQUERY NVARCHAR(MAX)
select @pivotcols=stuff((select ','+quotename(dates) from #tempp for xml path('')),1,1,'')
--select @pivotcols
select @unpivotcols=stuff((select ','+name from tempdb.sys.columns where object_id =
object_id('tempdb..#tempp') and name<>'DATES' for xml path('')),1,1,'')
--select @unpivotcols
SET @SQLQUERY=N'select * from (
SELECT * FROM #tempp
)as a
unpivot (AMOUNTS FOR Dates in ('+@unpivotcols+N')
) AS UNPI
PIVOT (MAX(AMOUNTS) FOR DATES IN ('+@pivotcols+N')
)AS A'
PRINT @SQLQUERY
EXEC SP_EXECUTESQL @SQLQUERY
输出就像。
+-----------------+------------+------------+------------+
| Dates | 2016-01-17 | 2016-01-18 | 2016-01-20|
+-----------------+------------+------------+------------+
| CANCELED_ORDERS | 50 | 20 | 30 |
| ORDERS | 100 | 120 | 150 |
+-----------------+------------+------------+------------+
答案 1 :(得分:0)
您需要分两部分来解决问题。
在第一部分中,使用SQL的 coalesce 函数连接您的日期和枢轴查询相同,但参数除外。
在第二部分中,使用动态SQL进行主数据透视查询,而不是静态日期传递保存日期的变量(您在第一部分中已经获得)
以下是我在项目中运行的查询,您必须替换其中的表逻辑。
Create Table #Temp (Salesdays int)
Insert into #Temp (Salesdays)values(7)
Insert into #Temp (Salesdays)values(14)
Insert into #Temp (Salesdays)values(30)
Insert into #Temp (Salesdays)values(90)
Insert into #Temp (Salesdays)values(180)
Insert into #Temp (Salesdays)values(365)
DECLARE @PivotColumns nVARCHAR(MAX)
SELECT @PivotColumns = COALESCE(@PivotColumns + ',[' + cast([Salesdays] as varchar(5))+']', '['+cast([Salesdays] as varchar(5))+']')
FROM #Temp
Print @PivotColumns
Declare @SQLQuery nVarchar(max)=N'Select
SellerSKU,
MarketPlaceCode,
isnull([7],0) as [SalesData_7],
isnull([14],0) as [SalesData_14],
isnull([30],0) as [SalesData_30],
isnull([90],0) as [SalesData_90],
isnull([180],0) as [SalesData_180],
isnull([365],0) as [SalesData_365]
from
(
Select
SellerSKU,
MPDetail.MarketPlaceCode,
Sum(QuantityShipped)QuantityShipped,
Case when (DATEDIFF(dd,OrderDetail.PurchaseDate,getDate()) <= 7 ) then 7
when (DATEDIFF(dd,OrderDetail.PurchaseDate,getDate()) <= 14 ) then 14
when (DATEDIFF(dd,OrderDetail.PurchaseDate,getDate()) <= 30 ) then 30
when (DATEDIFF(dd,OrderDetail.PurchaseDate,getDate()) <= 90 ) then 90
when (DATEDIFF(dd,OrderDetail.PurchaseDate,getDate()) <= 180 ) then 180
when (DATEDIFF(dd,OrderDetail.PurchaseDate,getDate()) <= 365 ) then 365 END as SalesDays
from OrderDetail
inner join MPDetail
on(OrderDetail.MPDetailID=MPDetail.MPDetailID)
inner join OrderItemDetail
on(OrderDetail.OrderDetailID=OrderItemDetail.OrderDetailID)
Group by SellerSKU,MPDetail.MarketPlaceCode,Case when (DATEDIFF(dd,OrderDetail.PurchaseDate,getDate()) <= 7 ) then 7
when (DATEDIFF(dd,OrderDetail.PurchaseDate,getDate()) <= 14 ) then 14
when (DATEDIFF(dd,OrderDetail.PurchaseDate,getDate()) <= 30 ) then 30
when (DATEDIFF(dd,OrderDetail.PurchaseDate,getDate()) <= 90 ) then 90
when (DATEDIFF(dd,OrderDetail.PurchaseDate,getDate()) <= 180 ) then 180
when (DATEDIFF(dd,OrderDetail.PurchaseDate,getDate()) <= 365 ) then 365 END
)
as SalesData
pivot
(
Min(QuantityShipped) For SalesDays in('+@PivotColumns+')
)AS USAPivotData'
Print @SQLQuery
exec (@SQLQuery)
答案 2 :(得分:0)
CREATE TABLE #t ( Dates DATE, Orders INT,CancelledOrders INT)
INSERT INTO #t
SELECT '2016-01-17',100 ,50 UNION
SELECT '2016-01-18',120 ,20 UNION
SELECT '2016-01-20',150 ,30
DECLARE @cols VARCHAR(max),@sql VARCHAR(MAX)
SELECT @cols=ISNULL(@cols+',[','[')+CONVERT(VARCHAR,dates)+']' FROM #t GROUP BY Dates
PRINT @cols
SET @sql=' SELECT * FROM (
SELECT c.t,c.v,dates FROM #t
CROSS APPLY(VALUES(''Orders'',Orders),(''CancelledOrders'',CancelledOrders))AS c(t,v)
) AS t
PIVOT(MAX(v) FOR dates IN ('+@cols+')) p'
EXEC(@sql)
t 2016-01-17 2016-01-18 2016-01-20 --------------- ----------- ----------- ----------- CancelledOrders 50 20 30 Orders 100 120 150
答案 3 :(得分:0)
不使用SQL Server的数据透视选项,旧版本可以是这样的:
declare @sql nvarchar(max) = '', @sqla nvarchar(max) = '', @sqlb nvarchar(max) = '', @sqlc nvarchar(max) = '';
select
@sqla = @sqla + N',case when Dates = ''' + Dates + N''' then Orders end [' + Dates + N']',
@sqlb = @sqlb + N',case when Dates = ''' + Dates + N''' then [Cancelled Orders] end [' + Dates + N']',
@sqlc = @sqlc + N',max([' + Dates + ']) [' + Dates + ']'
from yourTable;
select @sql = N'select Dates' + @sqlc + N' from (select ''Orders'' Dates' + @sqla +
N' from yourTable union all select ''Cancelled Orders'' Dates' + @sqlb +
N' from yourTable) t group by Dates';
exec(@sql);