2016-10-07 103 views
1

我正試圖確定在建設項目的生命週期中,基於面板狀態及時向面板添加額外負載到電源面板的效果。電源板可以有多個與其相關的負載(最多240個),並且這些負載可以在任何給定時間基於施工計劃進行安裝或卸載。面板上的負載總和在項目的生命週期中波動。僅僅因爲今天的負載爲90%,並不意味着你有10%的可用空間,因爲明天可能安裝新的負載。項目生命週期總是需要考慮。Aggregate基於多個日期範圍的值總和 - SQL Server

我需要一個查詢,該查詢將根據面板上所有負載的安裝/卸載日期確定給定日期的面板的最大負載。

以下是加載及其安裝/卸載日期的示例視圖。

CREATE TABLE #temp(
    PanelID  INTEGER NOT NULL 
    ,LOADID  INTEGER NOT NULL 
    ,Load  VARCHAR(7) NOT NULL 
    ,kVA   NUMERIC(5,2) NOT NULL 
    ,InstallDate DATE NOT NULL 
    ,DemoDate DATE 
); 
INSERT INTO #temp(PanelID,LOADID,Load,kVA,InstallDate,DemoDate) VALUES (1380,46706,'AUTO26',43.95,'07/07/1905','27/10/2016'); 
INSERT INTO #temp(PanelID,LOADID,Load,kVA,InstallDate,DemoDate) VALUES (1380,46706,'AUTO26',43.95,'07/07/1905','27/10/2016'); 
INSERT INTO #temp(PanelID,LOADID,Load,kVA,InstallDate,DemoDate) VALUES (1380,15539,'AUTO22',43.95,'01/01/2015',NULL); 
INSERT INTO #temp(PanelID,LOADID,Load,kVA,InstallDate,DemoDate) VALUES (1380,20188,'OVEN101',46.47,'29/06/2017',NULL); 
INSERT INTO #temp(PanelID,LOADID,Load,kVA,InstallDate,DemoDate) VALUES (1380,20186,'OVEN101',63.05,'29/06/2017',NULL); 
INSERT INTO #temp(PanelID,LOADID,Load,kVA,InstallDate,DemoDate) VALUES (1380,46705,'AUTO28',61.25,'07/07/1905','27/10/2016'); 
INSERT INTO #temp(PanelID,LOADID,Load,kVA,InstallDate,DemoDate) VALUES (1380,20186,'OVEN101',63.05,'29/06/2017',NULL); 
INSERT INTO #temp(PanelID,LOADID,Load,kVA,InstallDate,DemoDate) VALUES (1380,46705,'AUTO28',61.25,'07/07/1905','27/10/2016'); 
INSERT INTO #temp(PanelID,LOADID,Load,kVA,InstallDate,DemoDate) VALUES (1380,15539,'AUTO22',43.95,'01/01/2015',NULL); 
INSERT INTO #temp(PanelID,LOADID,Load,kVA,InstallDate,DemoDate) VALUES (1380,20188,'OVEN101',46.47,'29/06/2017',NULL); 
INSERT INTO #temp(PanelID,LOADID,Load,kVA,InstallDate,DemoDate) VALUES (1380,15538,'AUTO22',66.65,'01/01/2015',NULL); 
INSERT INTO #temp(PanelID,LOADID,Load,kVA,InstallDate,DemoDate) VALUES (1380,20187,'OVEN101',50.44,'29/06/2017',NULL); 
INSERT INTO #temp(PanelID,LOADID,Load,kVA,InstallDate,DemoDate) VALUES (1380,46704,'AUTO26',61.25,'07/07/1905','27/10/2016'); 
INSERT INTO #temp(PanelID,LOADID,Load,kVA,InstallDate,DemoDate) VALUES (1380,46707,'AUTO28',43.95,'07/07/1905','27/09/2016'); 
INSERT INTO #temp(PanelID,LOADID,Load,kVA,InstallDate,DemoDate) VALUES (1380,15538,'AUTO22',66.65,'01/01/2015',NULL); 
INSERT INTO #temp(PanelID,LOADID,Load,kVA,InstallDate,DemoDate) VALUES (1380,20187,'OVEN101',50.44,'29/06/2017',NULL); 
INSERT INTO #temp(PanelID,LOADID,Load,kVA,InstallDate,DemoDate) VALUES (1380,46704,'AUTO26',61.25,'07/07/1905','27/10/2016'); 
INSERT INTO #temp(PanelID,LOADID,Load,kVA,InstallDate,DemoDate) VALUES (1380,46707,'AUTO28',43.95,'07/07/1905','27/09/2016'); 

我的最新解決方案是使用遊標找到面板的負載(總和或千伏安),在與面板上的負載相關的每一個給定的日期。由於面板上可能會有240個負載,因此會導致性能下降。

有沒有更好的方法來做到這一點?

編輯:我已經簡化了創建表的建議。您只需按面板進行分組並彙總kVA列以檢索結果。但是,我希望基於面板上每個Load的安裝日期。如果卸載日期小於安裝日期,則它不應出現在聚合函數中。

+1

您的示例代碼無法運行。這是主鍵違規。有多個1375 SourceID時,他們需要是唯一的。 –

+0

我認爲你需要用你的問題做2件事才能得到更好的迴應。臨時表創建方法很好,但是看看這些字段,是否需要它們來表示問題,並且是否需要所有這些行?因此,將樣本數據簡化到最低要求,然後提供您期望輸出的樣子。此外,你目前的嘗試會很有用。 – Tanner

+0

此外,我在英國,所以得到:*轉換日期和/或時間從字符串轉換失敗*,最好格式化您的日期,如'yyyymmdd',SQL將永遠明白這一點。 – Tanner

回答

1

我假設DemoDate是一個負載從板上刪除的日期,null表示它們不會被刪除。這是一個常見的表格表達式查詢,它應該在整個持續時間內給出最大kVA:

SET DATEFORMAT dmy; 

CREATE TABLE #temp(
    SourceID  INTEGER  NOT NULL 
    ,PanelID  INTEGER  NOT NULL 
    ,BP_DP   INTEGER  NOT NULL 
    ,depth   BIT   NOT NULL 
    ,LOADID   INTEGER  NOT NULL 
    ,Load   VARCHAR(7)  NOT NULL 
    ,kVA   NUMERIC(5,2) NOT NULL 
    ,InstallDate DATE   NOT NULL 
    ,DemoDate  DATE 
); 

INSERT INTO #temp 
    (SourceID, PanelID, BP_DP, depth, LOADID, Load,  kVA, InstallDate, DemoDate ) 
VALUES 
    (1375,  1380, 2,  1,  46706, 'AUTO26', 43.95, '07/07/1905', '27/10/2016'), 
    (1380,  1380, 2,  0,  46706, 'AUTO26', 43.95, '07/07/1905', '27/10/2016'), 
    (1375,  1380, 2,  1,  15539, 'AUTO22', 43.95, '01/01/2015', NULL  ), 
    (1375,  1380, 2,  1,  20188, 'OVEN101', 46.47, '29/06/2017', NULL  ), 
    (1380,  1380, 2,  0,  20186, 'OVEN101', 63.05, '29/06/2017', NULL  ), 
    (1380,  1380, 2,  0,  46705, 'AUTO28', 61.25, '07/07/1905', '27/10/2016'), 
    (1375,  1380, 2,  1,  20186, 'OVEN101', 63.05, '29/06/2017', NULL  ), 
    (1375,  1380, 2,  1,  46705, 'AUTO28', 61.25, '07/07/1905', '27/10/2016'), 
    (1380,  1380, 2,  0,  15539, 'AUTO22', 43.95, '01/01/2015', NULL  ), 
    (1380,  1380, 2,  0,  20188, 'OVEN101', 46.47, '29/06/2017', NULL  ), 
    (1375,  1380, 2,  1,  15538, 'AUTO22', 66.65, '01/01/2015', NULL  ), 
    (1375,  1380, 2,  1,  20187, 'OVEN101', 50.44, '29/06/2017', NULL  ), 
    (1375,  1380, 2,  1,  46704, 'AUTO26', 61.25, '07/07/1905', '27/10/2016'), 
    (1375,  1380, 2,  1,  46707, 'AUTO28', 43.95, '07/07/1905', '27/10/2016'), 
    (1380,  1380, 2,  0,  15538, 'AUTO22', 66.65, '01/01/2015', NULL  ), 
    (1380,  1380, 2,  0,  20187, 'OVEN101', 50.44, '29/06/2017', NULL  ), 
    (1380,  1380, 2,  0,  46704, 'AUTO26', 61.25, '07/07/1905', '27/10/2016'), 
    (1380,  1380, 2,  0,  46707, 'AUTO28', 43.95, '07/07/1905', '27/10/2016'); 

WITH cte 
AS 
(
    SELECT 
     t1.PanelID, 
     t1.InstallDate, 
     SUM(t2.kVA) LoadAferInstall 
    FROM 
     (SELECT DISTINCT 
      PanelID, 
      InstallDate 
     FROM 
      #Temp 
     ) t1 
     JOIN #Temp t2 
      ON t1.PanelID = t2.PanelID 
      AND t2.InstallDate <= t1.InstallDate 
      AND (t2.DemoDate IS NULL OR t2.DemoDate >= t1.InstallDate) 
    GROUP BY 
     t1.PanelID, t1.InstallDate 
) 
SELECT 
    PanelID, 
    MAX(LoadAferInstall) MaxPanelLoad_kVA 
FROM 
    cte 
GROUP BY 
    PanelID 
; 

DROP TABLE #temp 
+0

這幾乎是正確的。但是,在總結結果之前,它似乎在複製行。有什麼想法嗎? – user1781272

+0

你的假設是準確的。但是,如果我刪除最後一個總計並檢查1905-07-07的總計負載,則它總計爲3360.它應該是961.在想什麼? – user1781272

+0

我已更新示例以刪除重複項。但是我不確定你從哪裏獲得961? 1905-07-07是第一個日期,因此這一天的總負載應該只是所有具有該InstallDate的行的總和?這個總數是420.80。 –