[英]SQL: Group SUM values by date ranges and show in multiple columns by date
[英]Aggregate Sum of values based on multiple date ranges - SQL Server
我正在尝试根据建筑项目生命周期中的面板状态及时确定向电源面板添加额外负载的效果。 配电盘可以有许多与其相关的负载(最多 240 个),并且可以在任何给定时间根据施工进度安装或卸载这些负载。 面板上的负载总和在项目的生命周期中波动。 仅仅因为今天的负载为 90%,并不自动意味着您有 10% 可用,因为可以安排明天安装新负载。 必须始终考虑项目生命周期。
我需要一个查询,根据面板上所有负载的安装/卸载日期确定给定日期面板的最大负载。
以下是负载及其安装/卸载日期的示例视图。
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');
迄今为止,我的解决方案是使用光标查找与面板上的负载相关的每个给定日期的面板负载(总和或 kVA)。 由于面板上最多可以有 240 个负载,这会对性能造成重大影响。
有没有更好的方法来做到这一点?
编辑:我已按照建议简化了创建表。 您只需按面板分组并对 kVA 列求和即可检索结果。 但是,我希望它基于面板上每个负载的安装日期。 如果卸载日期小于安装日期,则不应出现在聚合函数中。
我假设 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.