2012-03-26 115 views
2

我目前正在嘗試創建一個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周。他們還希望所有這些的平均值列。

據我所知pivot可以幫助我,但我有點難倒如何做到這一點。這是我當前的查詢:

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

+0

您能否向我們提供您想要的初始值和輸出? 「交貨」或「倉庫」表在哪裏存在日期欄? – Arion 2012-03-26 12:33:40

+0

什麼版本的TSQL? SQL Server?什麼版本的SQL Server? – JNK 2012-03-26 12:37:39

+0

問題修改,謝謝。我們正在運行SQL Server 2008 – Chris 2012-03-26 12:38:18

回答

3

你將不得不利用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

+0

謝謝 - 問題在於日期沒有硬編碼,這些將根據當前日期而改變。 – Chris 2012-03-26 13:48:11

+0

您可以用表格中實際的日期字段替換硬編碼的日期。我會在我的例子中包括這個,但是我不確定它在你的模式中涉及哪個字段。 – 2012-03-26 13:49:34

3

不知道你的確切數據。很難預測你會得到什麼。但我可以給你一個解決方案的建議。

表結構

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 ('[email protected]+') 
) AS pvt' 

EXECUTE(@query) 

再經過清理的日期欄我。

DROP TABLE Deliveries 
DROP TABLE Account 
DROP TABLE Depots 
DROP TABLE #tmp