SQL:根据开始和结束日期仅对某些行求和

时间:2015-12-10 21:11:16

标签: sql sql-server date datetime

我有两个表:第一个表包含唯一标识符(UI)。每个唯一标识符都有一个包含开始日期(yyyy-mm-dd)的列,以及一个包含结束日期(yyyy-mm-dd)的列。第二个表包含每天的温度,包括月,日,年和温度的单独列。我想加入这些表并获得每个唯一标识符的编译温度;但是,我将编译温度仅包括第二个表中距第一个表的开始日期和结束日期之间的天数。 例如,如果一条记录的start_date为12/10/15且结束日期为12/31/15,我希望有一个包含10 -31s的编译温度的列。如果下一条记录的开始日期为12/3 / 15-12 / 17/15,我希望它旁边的列显示第3至17日的编译温度。我将包含到目前为止的查询,但它没有太大帮助,因为我还没有真正走得太远:

; with Temps as (
    select MONTH, DAY, YEAR, Temp
    from Temperatures
    where MONTH = 12
    and YEAR = 2016
    )
    Select UI, start_date, end_date, location, SUM(temp)
    from Table1 t1
    Inner join Temps
    on temps.month = month(t1.start_date)

我感谢您提供的任何帮助。让我知道我需要详细说明任何事情。

Table 1     
UI  Start_Date  End_Date
2080    12/5/2015   12/31/2015
1266    12/1/2015   12/31/2015
1787    12/17/2015  12/28/2015
1621    12/3/2015   12/20/2015
1974    12/10/2015  12/12/2015
1731    12/25/2015  12/31/2015


Table 2         
    Month   Day Year    Temp
    12  1   2016    34
    12  2   2016    32
    12  3   2016    35
    12  4   2016    37
    12  5   2016    32
    12  6   2016    30
    12  7   2016    31
    12  8   2016    36
    12  9   2016    48
    12  10  2016    42
    12  11  2016    33
    12  12  2016    41
    12  13  2016    31
    12  14  2016    29
    12  15  2016    46
    12  16  2016    48
    12  17  2016    38
    12  18  2016    29
    12  19  2016    45
    12  20  2016    37
    12  21  2016    48
    12  22  2016    46
    12  23  2016    44
    12  24  2016    45
    12  25  2016    35
    12  26  2016    44
    12  27  2016    29
    12  28  2016    38
    12  29  2016    29
    12  30  2016    35
    12  31  2016    40

Table 3 (Expected Result)           
UI  Start_Date  End_Date    Compiled Temp
2080    12/5/2015   12/31/2015  1101
1266    12/1/2015   12/31/2015  1167
1787    12/17/2015  12/28/2015  478
1621    12/3/2015   12/20/2015  668
1974    12/10/2015  12/12/2015  126
1731    12/25/2015  12/31/2015  250

2 个答案:

答案 0 :(得分:0)

你可以这样做:

; WITH temps AS (
    SELECT CONVERT(DATE, CONVERT(CHAR(4), [YEAR]) + '-' + CONVERT(CHAR(2), [MONTH]) + '-' + CONVERT(VARCHAR(2), [DAY])) [TDate], [Temp]
    FROM Temperatures
    WHERE [MONTH] = 12
    AND [YEAR] = 2015
    ) 
    SELECT [UI], [start_date], [end_date]
        , (SELECT SUM([temp]) 
        FROM temps
        WHERE [TDate] BETWEEN T1.[start_date] AND T1.[end_date]) [Compiled Temp]
    FROM Table1 T1

无需加入。

答案 1 :(得分:0)

您也可以对这两个表进行简单连接。您不需要使用CTE。

--TEST DATA
if object_id('Table1','U') is not null
    drop table Table1

create table Table1 (UI int, Start_Date date, End_Date date)     

insert Table1
values
(2080,'12/05/2015','12/31/2015'),
(1266,'12/01/2015','12/31/2015'),
(1787,'12/17/2015','12/28/2015'),
(1621,'12/03/2015','12/20/2015'),
(1974,'12/10/2015','12/12/2015'),
(1731,'12/25/2015','12/31/2015')

if object_id('Table2','U') is not null
    drop table Table2

create table Table2 (Month int, Day int, Year int, Temp int)     

insert Table2
values
(12,1, 2015,34),
(12,2, 2015,32),
(12,3, 2015,35),
(12,4, 2015,37),
(12,5, 2015,32),
(12,6, 2015,30),
(12,7, 2015,31),
(12,8, 2015,36),
(12,9, 2015,48),
(12,10,2015,42),
(12,11,2015,33),
(12,12,2015,41),
(12,13,2015,31),
(12,14,2015,29),
(12,15,2015,46),
(12,16,2015,48),
(12,17,2015,38),
(12,18,2015,29),
(12,19,2015,45),
(12,20,2015,37),
(12,21,2015,48),
(12,22,2015,46),
(12,23,2015,44),
(12,24,2015,45),
(12,25,2015,35),
(12,26,2015,44)


--AGGREGATE TEMPS
select t1.Start_Date, t1.End_Date, avg(t2.temp) AvgTemp, sum(t2.temp) CompiledTemps
from table1 t1
    join table2 t2 ON t2.Year between datepart(year, t1.Start_Date) and datepart(year, t1.End_Date)
        and t2.Month          between datepart(month,t1.Start_Date) and datepart(month,t1.End_Date)
        and t2.Day            between datepart(day,  t1.Start_Date) and datepart(day,  t1.End_Date)
group by t1.Start_Date, t1.End_Date