T-SQL - Pivot по неделям - PullRequest
       64

T-SQL - Pivot по неделям

2 голосов
/ 26 марта 2012

В настоящее время я пытаюсь создать T-SQL, который просматривает список поставок в таблице и группирует их по клиенту и депо - поэтому каждая строка будет

клиент, депо, Общая стоимость (сумма столбца с именем Rate)

Однако клиент хотел бы, чтобы «общая стоимость» была разделена на последние 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

enter image description here

Ответы [ 2 ]

3 голосов
/ 26 марта 2012

Не зная ваших точных данных. Трудно предсказать, что вы получаете. Но я могу предложить вам решение.

Структура таблицы

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
3 голосов
/ 26 марта 2012

Вы должны использовать ключевое слово PIVOT, доступное в вашей версии SQL Server. Я обрисовал в общих чертах, как должен выглядеть ваш запрос, конечно, потребуется некоторая настройка, поскольку его сложно протестировать без копии ваших данных.

  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

...