【问题标题】:SQL SUM values of month, compare with same days of same month from previous year for specific names月份的 SQL SUM 值,与特定名称的上一年同月的同一天进行比较
【发布时间】:2014-12-17 00:13:58
【问题描述】:

因此请考虑以下表格:

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');

表 [meters] 具有 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

这似乎可行,但除了丑得可笑之外,我还需要另一件事,我不知道如何实现。例如,从名称上带有“ABC”的所有仪表中,如果其中一个仪表的值直到第 25 天,我的代码认为所有仪表的值直到第 25 天。 我怎样才能获得正确的结果(如果每个仪表在不同日期之前都有值)?

我使用的是 MS SQL 2008。

提前感谢您的帮助。

【问题讨论】:

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


    【解决方案1】:

    您可以使用条件聚合来做到这一点。这是一种方法

    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;
    

    【讨论】:

    • 找不到所选日期月份的最后一个记录日期。但我认为即使这样做也不会提供体面的结果。所以这最终完美地工作。谢谢!简单多了。最好的问候
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-22
    • 1970-01-01
    • 2020-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多