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

问题描述 投票:0回答:2

我有两个表第一个就是这个叫这个表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并把它作为一个连接以某种方式?

sql-server tsql
2个回答
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上有重复值,则与原始查询相比,可能会获得更少的行)。


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
© www.soinside.com 2019 - 2024. All rights reserved.