[英]T-SQL - Pivot by week
我目前正在尝试创建一个T-SQL,该T-SQL通过表中的交货清单运行,并按客户和仓库进行分组-因此每一行将
客户,仓库,总价值(称为费率的列的总和)
但是,客户希望将“总值”划分为最近9周-因此,我们将有以下列而不是总值:
22/01/2012 29/01/2012 05/02/2012 12/02/2012 19/02/2012 26/02/2012 04/03/2012 11/03/2012 18/03/2012
当他们运行查询时,日期当然会发生变化-只是最后9周。 他们还需要一列“所有平均值”。
我知道枢轴可能会帮助我,但我对如何执行此操作有些困惑。 这是我当前的查询:
SELECT d.Name AS 'Depot, s.Name AS 'Customer', SUM(c.Rates) AS 'Total Value'
FROM Deliveries AS c INNER JOIN Account AS s ON c.Customer = s.ID
INNER JOIN Depots AS d ON c.CollectionDepot = d.Letter
GROUP BY d.Name, s.Name
非常感谢!
编辑:这是当前数据的屏幕截图-我们不需要最后的“总计”列,只需向您展示。 “日期”列位于“交货”表中,称为TripDate
您必须使用在您的SQL Server版本中可用的PIVOT关键字。 我已经概述了查询的外观,当然,由于没有数据的副本很难进行测试,因此需要进行一些调整。
SELECT Depots.Name AS 'Depot', Account.Name, '22/01/2012', '29/01/2012', '05/02/2012', '12/02/2012',
FROM
(SELECT Name,
FROM Deliveries
INNER JOIN Account ON Deliveries.Customer = Account.ID
INNER JOIN Depots ON Account.CollectionDepot) AS Source
PIVOT
(
SUM(Deliveries.Rates)
FOR Date IN ('22/01/2012', '29/01/2012', '05/02/2012', '12/02/2012')
) AS 'Pivot Table'
作为参考,您可以以此为指导:
不知道您的确切数据。 很难预测你得到什么。 但我可以给您一个解决方案的建议。
表结构
CREATE TABLE Deliveries
(
Customer INT,
CollectionDepot INT,
Rates FLOAT,
TripDate DATETIME
)
CREATE TABLE Account
(
Name VARCHAR(100),
ID INT
)
CREATE TABLE Depots
(
Name VARCHAR(100),
Letter INT
)
测试数据
INSERT INTO Deliveries
VALUES
(1,1,452,GETDATE()-10),
(1,1,800,GETDATE()-30),
(1,1,7895,GETDATE()-2),
(1,1,451,GETDATE()-2),
(1,1,478,GETDATE()-89),
(1,1,4512,GETDATE()-31),
(1,1,782,GETDATE()-20),
(1,1,652,GETDATE()-5),
(1,1,752,GETDATE()-452)
INSERT INTO Account
VALUES
('Customer 1',1)
INSERT INTO Depots
VALUES
('Depot 1',1)
包含范围和格式日期的表
CREATE TABLE #tmp
(
StartDate DATETIME,
EndDate DATETIME,
FomatedDate VARCHAR(20)
)
计算日期范围
;WITH Nbrs ( n ) AS (
SELECT 0 UNION ALL
SELECT 1+n FROM Nbrs WHERE n < 8 )
INSERT INTO #tmp
SELECT
DATEADD(WEEK,-n-1,GETDATE()),
DATEADD(WEEK,-n,GETDATE()),
convert(varchar, DATEADD(WEEK,-n,GETDATE()), 112)
FROM
Nbrs
ORDER BY
-n
数据透视表的日期列
DECLARE @cols VARCHAR(MAX)
SELECT @cols = COALESCE(@cols + ','+QUOTENAME(FomatedDate),
QUOTENAME(FomatedDate))
FROM
#tmp
声明一些动态sql并执行它
DECLARE @query NVARCHAR(4000)=
N'SELECT
*
FROM
(
SELECT
Depots.Name AS Depot,
Account.Name AS Customer,
Deliveries.Rates,
tmp.FomatedDate,
AVG(Deliveries.Rates) OVER(PARTITION BY 1) AS Average,
SUM(Deliveries.Rates) OVER(PARTITION BY 1) AS Total
FROM
Deliveries
JOIN Account
ON Deliveries.Customer = Account.ID
JOIN Depots
ON Deliveries.CollectionDepot = Depots.Letter
JOIN #tmp AS tmp
ON Deliveries.TripDate BETWEEN tmp.StartDate AND tmp.EndDate
) AS p
PIVOT
(
AVG(rates)
FOR FomatedDate IN ('+@cols+')
) AS pvt'
EXECUTE(@query)
然后自己清理。
DROP TABLE Deliveries
DROP TABLE Account
DROP TABLE Depots
DROP TABLE #tmp
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.