Несколько объединений во временной таблице ИЛИ подзапрос в SQL 2008 - PullRequest
1 голос
/ 13 августа 2010

У меня есть следующий SQL, который получает сезон для каждого дня в диапазоне дат, затем группирует каждый сезон по дате начала и окончания по количеству ночей. Что это делает, это не важно, но мой вопрос в том, что лучше, как я это сделал ниже или использую первый оператор выбора в качестве подзапроса каждый раз, когда @dateSeasons используется во втором запросе. Оба пути, кажется, работают одинаково, но этот путь выглядит аккуратнее.

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])

Ответы [ 2 ]

0 голосов
/ 03 мая 2013

Иногда вы можете повысить производительность, используя общее табличное выражение (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])
0 голосов
/ 13 августа 2010

Взгляд аккуратнее не имеет значения при написании кода SQL.То, что выглядит элегантно, часто является худшим возможным способом решения проблемы с точки зрения производительности.

Единственный способ узнать наверняка, что лучше, - это сначала убедиться, что оба способа тестирования возвращают одинаковые результаты, а затем проверить их производительность и проверить планы выполнения (или объяснить в mySQL).Методы, которые делают запрос лучше, также зависят от базы данных.То, что лучше всего подходит для настройки производительности в SQL Server, может быть худшим вариантом в Oracle.

...