繁体   English   中英

T-SQL-每周透视

[英]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'

作为参考,您可以以此为指导:

http://msdn.microsoft.com/en-us/library/ms177410.aspx

不知道您的确切数据。 很难预测你得到什么。 但我可以给您一个解决方案的建议。

表结构

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM