从涉及其他两个日期之间的日期的查询中删除子查询

时间:2019-02-14 14:13:43

标签: sql-server tsql

我有两个表,第一个像这个表StartEndDates

| StartDate    | EndDate    | SomeOtherData |
|2018-09-08    | 2018-09-23 | data 1        |
|2018-07-08    | 2018-08-01 | data 2        |

另一个表就是这个表DataAndCreatedOn


| Data   | CreatedOn  |
| 1.5    | 2018-09-20 | 
| 2.4    | 2018-07-15 |
| 3.5    | 2018-07-21 |

所以现在我有这样的查询

Select sed.someotherdata
    , (select sum(data) 
       from DataAndCreatedOn 
       where CreatedOn between sed.StartDate and sed.EndDate) as total 
from StartEndDates sed

有没有办法摆脱子查询(select sum(data) from DataAndCreatedOn where CreatedOn between sed.StartDate and sed.EndDate) as total并以某种方式将其作为联接?

2 个答案:

答案 0 :(得分:1)

您可以使用JOINGROUP BY

SELECT
    sed.someotherdata,
    SUM(d.data) as total
FROM
    StartEndDates sed
    LEFT JOIN DataAndCreatedOn d ON d.CreatedOn BETWEEN sed.StartDate and sed.EndDate
GROUP BY
    sed.someotherdata

但是StartEndDates的行将被分组(如果您在someotherdata上有重复的值,则与原始查询相比,行数可能会减少)。

答案 1 :(得分:0)

如果您确实想摆脱该子查询,也可以使用CROSS APPLY,尽管执行计划几乎相同。正如@EzLo所指出的,从您的示例中将看到,如果您有重复的SomeOtherData,它将根据您执行的LEFT JOIN或CROSS APPLY来更改结果。因此,这取决于您希望从查询中得到什么。我还要注意查询性能:

CREATE TABLE #StartEndDates(StartDate  date, EndDate  date, SomeOtherData varchar(100))
CREATE TABLE #DateAndCreatedOn(Data decimal(10,4), CreatedOn date)

INSERT INTO #StartEndDates VALUES('2018-09-08', '2018-09-23', 'data 1')
INSERT INTO #StartEndDates VALUES('2018-07-08', '2018-08-01', 'data 2')
INSERT INTO #StartEndDates VALUES('2018-07-21', '2018-08-12', 'data 3')

--INSERT THIS ROW TO SEE DUPLICATE SomeOtherData
INSERT INTO #StartEndDates VALUES('2018-07-11', '2018-08-12', 'data 3')


INSERT INTO #DateAndCreatedOn VALUES(1.5,'2018-09-20')
INSERT INTO #DateAndCreatedOn VALUES(2.4,'2018-07-15')
INSERT INTO #DateAndCreatedOn VALUES(3.5,'2018-07-21')



--ORIGINAL QUERY
 Select sed.someotherdata
    , (select sum(data) 
       from #DateAndCreatedOn 
       where CreatedOn between sed.StartDate and sed.EndDate) as total 
from #StartEndDates sed


--LEFT JOIN QUERY
SELECT
    sed.someotherdata,
    SUM(d.data) as total
FROM
    #StartEndDates sed
    LEFT JOIN #DateAndCreatedOn d ON d.CreatedOn BETWEEN sed.StartDate and sed.EndDate
GROUP BY
    sed.someotherdata


--CROSS APPLY QUERY
 SELECT sed.SomeOtherData, x.SM
 FROM #StartEndDates sed
 CROSS APPLY (SELECT SUM(Data) SM  from #DateAndCreatedOn d where d.CreatedOn between sed.StartDate and sed.EndDate) x
相关问题