Pivot sql将行转换为列
下面的查询得到以下输出Pivot sql将行转换为列,sql,sql-server,Sql,Sql Server,下面的查询得到以下输出 Service Date Product1 Product2 01/Jun/2015 1 3 02/Jun/2015 2 5 相反,我希望日期在列中,所以out put应该是这样的 Products 01/Jun/2015 02/Jun/2015 Product1 1 3 Product2 2 5 查询 DECLARE @cols AS nvarchar(
Service Date Product1 Product2
01/Jun/2015 1 3
02/Jun/2015 2 5
相反,我希望日期在列中,所以out put应该是这样的
Products 01/Jun/2015 02/Jun/2015
Product1 1 3
Product2 2 5
查询
DECLARE @cols AS nvarchar(max),
@query AS nvarchar(max)
SELECT
@cols = STUFF((SELECT
',' + QUOTENAME(Product_Name)
FROM dbo.Store where CatID='2'
GROUP BY Product_Name
ORDER BY Product_Name
FOR xml PATH (''), TYPE)
.value('.', 'NVARCHAR(MAX)'), 1, 1, '')
SET @query = 'SELECT Replace(CONVERT(NVARCHAR, Service_Date, 106), '' '', ''/'') AS [Service Date],' + @cols + ' from ( select Service.Service_Date, Store.Product_Name, Servicelist.ProductQty FROM dbo.Service INNER JOIN dbo.Servicelist ON dbo.Service.Service_ID = dbo.Servicelist.Service_ID INNER JOIN dbo.Store ON dbo.Servicelist.Pro_ID = dbo.Store.Pro_ID) x pivot ( SUM(ProductQty) for Product_Name in (' + @cols + ') ) p '
EXECUTE (@query);
您当前的查询是以产品名称为轴心并对日期进行分组。但是,您需要重点关注日期并对产品名称进行分组
SELECT @cols = Stuff((SELECT ','
+ Quotename(CONVERT(char(11), Service_Date, 106))
FROM dbo.Store
WHERE CatID = '2'
GROUP BY CONVERT(char(11), Service_Date, 106)
ORDER BY CONVERT(date, Service_Date)
FOR xml PATH (''), TYPE) .value('.', 'NVARCHAR(MAX)'), 1, 1, '')
这样试试
DECLARE @cols AS NVARCHAR(max),
@query AS NVARCHAR(max)
查找不同的日期列表,而不是产品名称
SELECT @cols = Stuff((SELECT ','
+ Quotename(CONVERT(char(11), Service_Date, 106))
FROM dbo.Store
WHERE CatID = '2'
GROUP BY CONVERT(char(11), Service_Date, 106)
ORDER BY CONVERT(date, Service_Date)
FOR xml PATH (''), TYPE) .value('.', 'NVARCHAR(MAX)'), 1, 1, '')
在pivotfor
列表中,使用Service\u date
列而不是Product\u Name
SET @query = 'SELECT Product_Name,'
+ @cols
+ ' from ( select Service.Service_Date, Store.Product_Name, Servicelist.ProductQty FROM dbo.Service INNER JOIN dbo.Servicelist ON dbo.Service.Service_ID = dbo.Servicelist.Service_ID INNER JOIN dbo.Store ON dbo.Servicelist.Pro_ID = dbo.Store.Pro_ID) x pivot ( SUM(ProductQty) for CONVERT(char(11), Service_Date, 106) in ('
+ @cols + ') ) p '
EXECUTE (@query);
这是如何使用普通的ANSI SQL完成的 首先,您需要垂直透视(TRANSACT-SQL中的UNPIVOT),这是通过交叉连接一个具有与“UNPIVOT”值相同数量的连续整数的单列临时表来实现的。在值的表达式中使用这些整数作为索引 然后,使用SUM(CASE-WHEN…)表达式重新透视,并按希望在第一列中垂直查看其值的列进行分组 下面是:
WITH
-- input
input(Service_Date,Product1,Product2) AS (
SELECT DATE '2015-06-01',1,3
UNION ALL SELECT DATE '2015-06-02',2,5
)
,
-- start vertical pivot: two integers
two_ints(idx) AS (SELECT 1 UNION ALL SELECT 2)
,
-- vertical pivot: CROSS JOIN input with two integers
vert_pivot AS (
SELECT
Service_Date
, idx
, 'Product'||CAST(idx AS CHAR(1)) AS product
, CASE idx WHEN 1 THEN Product1 WHEN 2 THEN Product2 END AS qty
FROM input CROSS JOIN two_ints
)
-- debug
-- SELECT * FROM vert_pivot;
-- Service_Date|idx|product |qty
-- 2015-06-01 | 1|Product1| 1
-- 2015-06-01 | 2|Product2| 3
-- 2015-06-02 | 1|Product1| 2
-- 2015-06-02 | 2|Product2| 5
,
-- re-pivot horizontally by date
horiz_pivot_dt AS (
SELECT
product
, SUM(CASE Service_Date WHEN '2015-06-01' THEN qty END) AS "2015-06-01"
, SUM(CASE Service_Date WHEN '2015-06-02' THEN qty END) AS "2015-06-02"
FROM vert_pivot
GROUP BY
product
)
SELECT * FROM horiz_pivot_dt
;
-- result:
-- product |2015-06-01|2015-06-02
-- Product1| 1| 2
-- Product2| 3| 5
顺便说一句:我注意到您只关注“列名”和第一列的值,而不是度量值。我上面的例子就是这样,我花了几分钟试图找出我的错误在哪里
玩得开心。。。
马可