SQL как выбрать дату из 1 - много - PullRequest
1 голос
/ 11 мая 2011

В хранимой процедуре SQL 2005 мне нужно выполнить запрос, который содержит 1-M.Мне нужно вернуть только одну из таблицы «Много» ту, которая имеет самую раннюю дату.

Я посмотрел на В SQL как мне написать запрос, чтобы вернуть 1 запись из отношения 1 ко многим?

и Загадка SQL, как выбрать последнюю дату для детали, но только 1 строка на деталь (уникальная)

Но я не уверен, что является лучшим решениемв моем случае, поскольку я также делаю временную таблицу Insert Into и использую динамическую сортировку и разбиение на страницы.

Вот мой SQL.Я хочу вернуть много строк Foo, но только самые ранние b.CreatedDate между начальными и конечными параметрами, которые я передаю, где в Bar обычно около 5 строк для каждого Foo.

DECLARE      @StartDate datetime 
 DECLARE     @EndDate datetime 

INSERT INTO @Results
          SELECT distinct
                f.Name,
                 f.Price
                b.CreatedDate ,
                // loads more columns removed for brevity   
          FROM
                foo f
            join bar b on f.Id = b.fooId
               // loads more table removed for brevity 
          WHERE
                (@x is null OR f.Id = @x)
            AND (@Deal is null OR f.IsDeal = @Deal)
            AND (@StartDate is null OR sd.SailingDate >= @StartDate)
            AND (@EndDate is null OR sd.SailingDate <= @EndDate)
                  // loads more filters removed for brevity 

        declare @firstResult int, @lastResult int
        set @firstResult = ((@PageNumber-1) * @ItemsPerPage) + 1;
        set @lastResult = @firstResult + @ItemsPerPage;
        select @TotalResults = count(1) from @Results;

        WITH ResultItems AS
        (
            SELECT *, ROW_NUMBER() OVER (
                ORDER BY
                CASE    WHEN @SortBy = 'priceLow' THEN Price END ASC,
                CASE    WHEN @SortBy = 'Soonest' THEN CreatedDate END ASC,
                CASE    WHEN @SortBy = 'priceHigh' THEN Price END DESC
            ) As  RowNumber
            FROM @Results r
        )
        SELECT * from ResultItems
        WHERE RowNumber >= @firstResult AND RowNumber < @lastResult
        ORDER BY
        CASE
            WHEN @SortBy = 'priceHigh' THEN (RANK() OVER (ORDER BY Price desc))
            WHEN @SortBy = 'priceLow' THEN (RANK() OVER (ORDER BY Price))
            WHEN @SortBy = 'Soonest' THEN (RANK() OVER (ORDER BY CreatedDate )) 
        END 

Этот запрос, как есть, будет возвращать несколько 'b.CreatedDate' вместо только самого раннего из моих фильтров

Обновление Поэтому я хочу посмотреть, если мои исходные данные:

Foo
___
1  , Hello
2  , There

Boo
___
1, 1,   2011-2-4
2, 1,   2011-3-6
3, 1,   2012-12-21
4, 2,   2012-11-2

Результат будет

1, Hello,2011-2-4
2, There,  2012-11-2

1 Ответ

0 голосов
/ 11 мая 2011

Я думаю, что я только что заработал, добавив CTE в начало моего запроса

;with cteMinDate as (
    select FooId, min(CreatedDate) As CreatedDate
    from Bar            WHERE
          (@StartDate is null OR CreatedDate>= @StartDate)
          AND (@EndDate is null OR CreatedDate<= @EndDate)
        group by FooId
)

То же, что показано здесь Загадка SQL, как выбрать самую последнюю дату для детали, но только 1 строка на деталь (уникальная) . Это позволяет мне удалить часть запроса даты из моего основного запроса и сделать это только один раз в CTE

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...