繁体   English   中英

SQL 2008中的临时表或子查询上的多个联接

[英]Multiple Joins on Temporary Table OR Subquery in SQL 2008

我有以下SQL,它在日期范围内的每一天获取一个季节,然后按开始日期和结束日期以及夜晚数将每个季节分组。 它的作用并不重要,但我的问题是,哪种方法更好,我在下面做了什么,还是在第二个查询中每次使用@dateSeasons时都将第一个select语句用作子查询。 两种方法似乎运行相同,但这种方法看起来更整洁。

DECLARE @dateSeasons TABLE ([date] date, seasonID int)

INSERT INTO @dateSeasons
SELECT D.[date], S.ID
FROM @dates AS D
CROSS APPLY (

    SELECT TOP 1 ID
    FROM dbo.Seasons
    WHERE bookingID = @bookingID 
    AND D.[date] BETWEEN startDate AND endDate
    ORDER BY ID DESC

) AS S


SELECT MIN([date]), endDate, DATEDIFF(DAY, MIN([date]), DATEADD(DAY, 1, endDate)), seasonID
FROM (

    SELECT S1.seasonID, S1.[date], (

        SELECT MAX([date])
        FROM @dateSeasons S2
        WHERE S2.seasonID = S1.seasonID
        AND NOT EXISTS (

            SELECT NULL
            FROM @dateSeasons S3
            WHERE S3.[date] < S2.[date]
            AND S3.[date] > S1.[date]
            AND S3.seasonID <> S1.seasonID

        )

    ) AS endDate
    FROM @dateSeasons S1
) AS results
GROUP BY endDate, seasonID
ORDER BY MIN([date])

有时,您可以通过使用公用表表达式 (CTE)获得更好的性能:

WITH
dateSeasons ([date], [seasonID])
AS
(
    SELECT D.[date], S.ID
    FROM @dates AS D
    CROSS APPLY (

        SELECT TOP 1 ID
        FROM dbo.Seasons
        WHERE bookingID = @bookingID 
        AND D.[date] BETWEEN startDate AND endDate
        ORDER BY ID DESC

    ) AS S
)

SELECT MIN([date]), endDate, DATEDIFF(DAY, MIN([date]), DATEADD(DAY, 1, endDate)), seasonID
FROM (

    SELECT S1.seasonID, S1.[date], (

        SELECT MAX([date])
        FROM dateSeasons S2
        WHERE S2.seasonID = S1.seasonID
        AND NOT EXISTS (

            SELECT NULL
            FROM dateSeasons S3
            WHERE S3.[date] < S2.[date]
            AND S3.[date] > S1.[date]
            AND S3.seasonID <> S1.seasonID

        )

    ) AS endDate
    FROM dateSeasons S1
) AS results
GROUP BY endDate, seasonID
ORDER BY MIN([date])

看起来整洁编写SQL代码无关 从性能的角度来看,看起来优雅的东西通常是解决问题的最糟糕的方法。

唯一确定哪种方法最好的方法是,首先确保所测试的两种方法都返回相同的结果,然后对它们进行性能测试,然后检查执行计划(或在mySQL中进行说明)。 使查询更好的技术也是特定于数据库的。 在SQL Server中最适合性能调整的方法可能是Oracle中最糟糕的可能性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM