SQL SUM值的月份,与特定名称的上一年同月相同

时间:2014-12-17 00:13:58

标签: sql sql-server sql-server-2008 datetime join

请考虑以下表格:



CREATE TABLE meters (meterentryid int, datasourcetag varchar(20));
 
INSERT INTO meters (meterentryid, datasourcetag) VALUES
('1', 'HABCQW'),
('2', 'BBBWEQ'),
('3', 'CCCQWD'),
('4', 'DDDQWD'),
('5', 'QABCDQ'),
('6', 'GABCQDT');

create table meter_values (meterentryid int, summary_value int, startdate datetime);

insert into meter_values (meterentryid, startdate, summary_value) values
('1','2013-09-01','8400'),
('2','2013-09-01','7500'),
('3','2013-09-01','8100'),
('4','2013-09-01','7500'),
('5','2013-09-01','9300'),
('6','2013-09-01','7100'),
('1','2013-10-01','84'),
('2','2013-10-01','75'),
('3','2013-10-01','81'),
('4','2013-10-01','75'),
('5','2013-10-01','93'),
('6','2013-10-01','71'),
('1','2013-10-02','76'),
('2','2013-10-02','94'),
('3','2013-10-02','91'),
('4','2013-10-02','92'),
('5','2013-10-02','93'),
('6','2013-10-02','72'),
('1','2013-10-03','92'),
('2','2013-10-03','70'),
('3','2013-10-03','75'),
('4','2013-10-03','84'),
('5','2013-10-03','76'),
('6','2013-10-03','77'),
('1','2013-10-04','91'),
('2','2013-10-04','97'),
('3','2013-10-04','93'),
('4','2013-10-04','85'),
('5','2013-10-04','79'),
('6','2013-10-04','98'),
('1','2013-10-05','98'),
('2','2013-10-05','85'),
('3','2013-10-05','95'),
('4','2013-10-05','98'),
('5','2013-10-05','86'),
('6','2013-10-05','95'),
('1','2013-10-06','97'),
('2','2013-10-06','75'),
('3','2013-10-06','98'),
('4','2013-10-06','94'),
('5','2013-10-06','97'),
('6','2013-10-06','84'),
('1','2013-10-07','81'),
('2','2013-10-07','96'),
('3','2013-10-07','94'),
('4','2013-10-07','98'),
('5','2013-10-07','96'),
('6','2013-10-07','79'),
('1','2013-10-08','86'),
('2','2013-10-08','100'),
('3','2013-10-08','79'),
('4','2013-10-08','98'),
('5','2013-10-08','95'),
('6','2013-10-08','85'),
('1','2013-10-09','72'),
('2','2013-10-09','94'),
('3','2013-10-09','76'),
('4','2013-10-09','86'),
('5','2013-10-09','76'),
('6','2013-10-09','98'),
('1','2013-10-10','93'),
('2','2013-10-10','94'),
('3','2013-10-10','75'),
('4','2013-10-10','80'),
('5','2013-10-10','99'),
('6','2013-10-10','77'),
('1','2013-10-11','72'),
('2','2013-10-11','84'),
('3','2013-10-11','93'),
('4','2013-10-11','74'),
('5','2013-10-11','89'),
('6','2013-10-11','70'),
('1','2013-10-12','100'),
('2','2013-10-12','71'),
('3','2013-10-12','81'),
('4','2013-10-12','98'),
('5','2013-10-12','85'),
('6','2013-10-12','92'),
('1','2013-10-13','77'),
('2','2013-10-13','75'),
('3','2013-10-13','95'),
('4','2013-10-13','74'),
('5','2013-10-13','95'),
('6','2013-10-13','91'),
('1','2013-10-14','97'),
('2','2013-10-14','91'),
('3','2013-10-14','79'),
('4','2013-10-14','73'),
('5','2013-10-14','89'),
('6','2013-10-14','85'),
('1','2013-10-15','83'),
('2','2013-10-15','74'),
('3','2013-10-15','91'),
('4','2013-10-15','100'),
('5','2013-10-15','89'),
('6','2013-10-15','88'),
('1','2013-10-16','77'),
('2','2013-10-16','70'),
('3','2013-10-16','76'),
('4','2013-10-16','72'),
('5','2013-10-16','77'),
('6','2013-10-16','89'),
('1','2013-10-17','80'),
('2','2013-10-17','81'),
('3','2013-10-17','79'),
('4','2013-10-17','73'),
('5','2013-10-17','83'),
('6','2013-10-17','93'),
('1','2013-10-18','80'),
('2','2013-10-18','72'),
('3','2013-10-18','94'),
('4','2013-10-18','73'),
('5','2013-10-18','76'),
('6','2013-10-18','96'),
('1','2013-10-19','97'),
('2','2013-10-19','98'),
('3','2013-10-19','96'),
('4','2013-10-19','83'),
('5','2013-10-19','87'),
('6','2013-10-19','97'),
('1','2013-10-20','75'),
('2','2013-10-20','86'),
('3','2013-10-20','78'),
('4','2013-10-20','73'),
('5','2013-10-20','84'),
('6','2013-10-20','100'),
('1','2013-10-21','70'),
('2','2013-10-21','87'),
('3','2013-10-21','98'),
('4','2013-10-21','99'),
('5','2013-10-21','74'),
('6','2013-10-21','77'),
('1','2013-10-22','77'),
('2','2013-10-22','90'),
('3','2013-10-22','83'),
('4','2013-10-22','93'),
('5','2013-10-22','77'),
('6','2013-10-22','90'),
('1','2013-10-23','83'),
('2','2013-10-23','92'),
('3','2013-10-23','78'),
('4','2013-10-23','86'),
('5','2013-10-23','84'),
('6','2013-10-23','77'),
('1','2013-10-24','82'),
('2','2013-10-24','83'),
('3','2013-10-24','81'),
('4','2013-10-24','83'),
('5','2013-10-24','72'),
('6','2013-10-24','72'),
('1','2013-10-25','75'),
('2','2013-10-25','79'),
('3','2013-10-25','87'),
('4','2013-10-25','86'),
('5','2013-10-25','89'),
('6','2013-10-25','96'),
('1','2013-10-26','88'),
('2','2013-10-26','89'),
('3','2013-10-26','100'),
('4','2013-10-26','81'),
('5','2013-10-26','88'),
('6','2013-10-26','78'),
('1','2013-10-27','100'),
('2','2013-10-27','98'),
('3','2013-10-27','70'),
('4','2013-10-27','81'),
('5','2013-10-27','94'),
('6','2013-10-27','73'),
('1','2013-10-28','86'),
('2','2013-10-28','83'),
('3','2013-10-28','85'),
('4','2013-10-28','100'),
('5','2013-10-28','70'),
('6','2013-10-28','98'),
('1','2013-10-29','82'),
('2','2013-10-29','78'),
('3','2013-10-29','74'),
('4','2013-10-29','86'),
('5','2013-10-29','87'),
('6','2013-10-29','71'),
('1','2013-10-30','88'),
('2','2013-10-30','71'),
('3','2013-10-30','97'),
('4','2013-10-30','95'),
('5','2013-10-30','97'),
('6','2013-10-30','81'),
('1','2013-10-31','96'),
('2','2013-10-31','78'),
('3','2013-10-31','82'),
('4','2013-10-31','74'),
('5','2013-10-31','84'),
('6','2013-10-31','95'),
('1','2014-10-01','70'),
('2','2014-10-01','97'),
('3','2014-10-01','73'),
('4','2014-10-01','79'),
('5','2014-10-01','81'),
('6','2014-10-01','81'),
('1','2014-10-02','70'),
('2','2014-10-02','73'),
('3','2014-10-02','85'),
('4','2014-10-02','78'),
('5','2014-10-02','81'),
('6','2014-10-02','74'),
('1','2014-10-03','74'),
('2','2014-10-03','93'),
('3','2014-10-03','81'),
('4','2014-10-03','70'),
('5','2014-10-03','83'),
('6','2014-10-03','79'),
('1','2014-10-04','80'),
('2','2014-10-04','97'),
('3','2014-10-04','96'),
('4','2014-10-04','89'),
('5','2014-10-04','79'),
('6','2014-10-04','98'),
('1','2014-10-05','83'),
('2','2014-10-05','95'),
('3','2014-10-05','96'),
('4','2014-10-05','77'),
('5','2014-10-05','77'),
('6','2014-10-05','71'),
('1','2014-10-06','96'),
('2','2014-10-06','89'),
('3','2014-10-06','99'),
('4','2014-10-06','83'),
('5','2014-10-06','90'),
('6','2014-10-06','89'),
('1','2014-10-07','98'),
('2','2014-10-07','76'),
('3','2014-10-07','86'),
('4','2014-10-07','79'),
('5','2014-10-07','76'),
('6','2014-10-07','97'),
('1','2014-10-08','94'),
('2','2014-10-08','78'),
('3','2014-10-08','83'),
('4','2014-10-08','90'),
('5','2014-10-08','92'),
('6','2014-10-08','91'),
('1','2014-10-09','90'),
('2','2014-10-09','85'),
('3','2014-10-09','84'),
('4','2014-10-09','90'),
('5','2014-10-09','95'),
('6','2014-10-09','94'),
('1','2014-10-10','94'),
('2','2014-10-10','81'),
('3','2014-10-10','78'),
('4','2014-10-10','74'),
('5','2014-10-10','90'),
('6','2014-10-10','74'),
('1','2014-10-11','98'),
('2','2014-10-11','83'),
('3','2014-10-11','79'),
('4','2014-10-11','87'),
('5','2014-10-11','93'),
('6','2014-10-11','78'),
('1','2014-10-12','96'),
('2','2014-10-12','77'),
('3','2014-10-12','74'),
('4','2014-10-12','99'),
('5','2014-10-12','84'),
('6','2014-10-12','95'),
('1','2014-10-13','74'),
('2','2014-10-13','97'),
('3','2014-10-13','99'),
('4','2014-10-13','82'),
('5','2014-10-13','72'),
('6','2014-10-13','73'),
('1','2014-10-14','96'),
('2','2014-10-14','78'),
('3','2014-10-14','91'),
('4','2014-10-14','97'),
('5','2014-10-14','76'),
('6','2014-10-14','84'),
('1','2014-10-15','98'),
('2','2014-10-15','81'),
('3','2014-10-15','100'),
('4','2014-10-15','93'),
('5','2014-10-15','90'),
('6','2014-10-15','78'),
('1','2014-10-16','81'),
('2','2014-10-16','94'),
('3','2014-10-16','97');




表[米]具有ID和名称,表[meter_values]具有在给定日期为每个仪表记录的值。

我想指定一个日期(外部),例如' 2014-10-10',检查所选月份的哪一天我在[meter_values]上有值。从去年(同月,直到同一天)获取相应的值,并在同一行上进行比较。因此,如果在所选日期的第一年我只有值直到第16天,我应该只比较直到最后一个月的第16天的值,尽管有所有值。 这应仅针对名称为' ABC'在他们身上。

所以结果表应该看起来像这样(没有手动完成数学检查):



Selected_Year |	Previous_Year |	Name
1392	      | 1376	      | HABCQW
1259	      | 1414	      | QABCDQ
1256	      | 1351	      | GABCQDT




我已经成功地完成了下面的SQL代码,我有点羞于向你们展示



select final.Selected_Year, final.Previous_Year, datasourcetag from
(
Select table1.sum_summary_value as 'Selected_Year', table2.sum_summary_value as 'Previous_Year', table1.MeterEntryID from
(
SELECT sum([Summary_Value]) as 'sum_summary_value', meters.MeterEntryID, DATEPART(yyyy,startdate) as 'Years'
FROM meter_values
INNER JOIN meters
ON meters.MeterEntryID=meter_values.MeterEntryID
where DataSourceTag like '%ABC%' and
DATEPART(dd,startdate) <= DATEPART(dd,
(
select top 1 startdate 
from meter_values
where 
datepart(mm,[StartDate])=datepart(mm,'2014-10-20') 
and datepart(yyyy,[StartDate])=datepart(yyyy,'2014-10-20') 
order by startdate desc
)
)
and 
(datepart(yyyy,[StartDate])=datepart(yyyy,'2014-10-20') 
or
datepart(yyyy,[StartDate])=datepart(yyyy,dateadd(yyyy,-1,'2014-10-20'))) 
and datepart(mm,[StartDate])=datepart(mm,'2014-10-20') 
group by METERS.MeterEntryID , DATEPART(yyyy,startdate) , DATEPART(mm,startdate)
) 
table1
full join
(
SELECT sum([Summary_Value]) as 'sum_summary_value', meters.MeterEntryID, DATEPART(yyyy,startdate) as 'Years'
FROM meter_values
INNER JOIN meters
ON meters.MeterEntryID=meter_values.MeterEntryID
where DataSourceTag like '%ABC%' and
DATEPART(dd,startdate) <= DATEPART(dd,
(
select top 1 startdate 
from meter_values
where 
datepart(mm,[StartDate])=datepart(mm,'2014-10-20') 
and datepart(yyyy,[StartDate])=datepart(yyyy,'2014-10-20') 
order by startdate desc
)
)
and 
(datepart(yyyy,[StartDate])=datepart(yyyy,'2014-10-20') 
or
datepart(yyyy,[StartDate])=datepart(yyyy,dateadd(yyyy,-1,'2014-10-20'))) 
and datepart(mm,[StartDate])=datepart(mm,'2014-10-20') 
group by METERS.MeterEntryID , DATEPART(yyyy,startdate) , DATEPART(mm,startdate)
)  
table2  
on table1.MeterEntryID=table2.MeterEntryID
where table1.years=datepart(yyyy,'2014-10-20') and table2.years=datepart(yyyy,dateadd(yyyy,-1,'2014-10-20')) 
)
final
inner join dbo.meters
on dbo.meters.meterentryid=final.meterentryid
&#13;
&#13;
&#13;

这似乎有效,但除了可笑的丑陋外,我还需要另外一件我不知道如何实现的事情。来自所有有ABC&#39; ABC的电表。在名称上,例如,如果其中一个值具有直到第25天的值,则我的代码认为所有的仪表都具有直到第25天的值。 如何才能获得正确的结果(如果每个仪表的值都有不同的天数)?

我正在使用MS SQL 2008。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

您可以使用条件聚合执行此操作。这是一种方法

select m.name,
       sum(case when year(startdate) = 2014 and day(startdate) <= 10 then summary_value end) as thisyear,
       sum(case when year(startdate) = 2013 and day(startdate) <= 10 then summary_value end) as lastyear
from meters m join
     meter_values mv
     on m.meterentryid = mv.emterentryid
where year(startdate) in (2013, 2014) and
      month(startdate) = 10
group by m.name;

编辑:

如果您愿意,可以将其概括为任何日期:

with d as (
      select date('2014-10-10') as dte
     )
select m.name,
       sum(case when year(startdate) = 2014 and day(startdate) <= day(d.dte) then summary_value end) as thisyear,
       sum(case when year(startdate) = 2013 and day(startdate) <= day(d.dte) then summary_value end) as lastyear
from d cross join
     meters m join
     meter_values mv
     on m.meterentryid = mv.emterentryid
where year(startdate) (year(d.dte), year(d.dte) - 1) and
      month(startdate) = month(d.dte)
group by m.name;