Улучшите Sql Query с помощью функции select max () в предложении where - PullRequest
3 голосов
/ 30 сентября 2009

Цель этого запроса - вернуть товары и их цены на товары, выставленные на продажу, и цена должна быть с даты, ближайшей к ней, но не равной дате, переданной, по сути, самой последней доступной цене. Там нет ценовых записей на каждый день. Что-то не так с наличием агрегатного оператора select в предложении where. Есть лучший способ сделать это? Может быть в критериях объединения?

        select  
        p.ProductName,
        pp.Price,
        pp.Date,
        from product p
        inner join productprice pp  on p.productid = pp.productid
        where 
        pp.evaluationdate = (select  max(Date) from productprice 
                             where productid = p.productid  
                             and date < @DateIn) 
        and p.producttype = 'OnSale'

На самом деле запрос немного сложнее, но это, по сути, проблема. Спасибо за ваш вклад.

EDIT Будет возвращено более одного продукта

EDIT Я экспериментирую с предложениями @Remus Rusanu и @ km (хотя @Remus Rusanu удалил его), все три, включая мой оригинал, кажутся примерно одинаковыми с точки зрения производительности. Я пытаюсь решить, предлагает ли один преимущество над другими каким-то другим нематериальным способом, то есть обслуживанием, самодокументированием и т. Д., Поскольку это будет поддерживаться кем-то другим. Еще раз спасибо.

Ответы [ 3 ]

5 голосов
/ 30 сентября 2009

попробуйте это:

;WITH CurrentPrice AS 
(
SELECT productid,max(Date) AS Date
    FROM productprice 
    WHERE date < @DateIn 
    GROUP BY productid
)

select  
    p.ProductName,
    pp.Price,
    pp.Date,
    from product p
        inner join CurrentPrice pa  on p.productid = pa.productid
        inner join productprice pp  on pa.productid = pp.productid AND pa.Date=pp.Date
    where p.producttype = 'OnSale'

РЕДАКТИРОВАТЬ на основании комментария ОП:

Я думаю, что вышеупомянутый запрос с CTE будет иметь тот же план запроса, что и версия производной таблицы от @Remus Rusanu

Однако, если таблица productprice большая, вы можете уменьшить ее, отфильтровав по «OnSale», как здесь:

;WITH CurrentPrice AS 
(
select  
    p.productid,
    MAX(pp.Date) AS Date
    from product p
        inner join productprice pp  on pa.productid = pp.productid
    where p.producttype = 'OnSale' AND pp.date < @DateIn 
    GROUP BY productid
)
select  
    p.ProductName,
    pp.Price,
    pp.Date,
    from CurrentPrice           pa
        inner join product      p   on pa.productid = p.productid
        inner join productprice pp  on pa.productid = pp.productid AND pa.Date=pp.Date
    where p.producttype = 'OnSale'
1 голос
/ 01 октября 2009

Это работа для оконных функций?

    SELECT * FROM (select  
            p.ProductName,
            pp.Price,
            pp.Date,
            RANK() OVER(PARTITION BY p.ProductId ORDER BY pp.Date DESC) as row_rank
            from product p
              join productprice pp  on p.productid = pp.productid
            where 
              pp.date < @DateIn
              and p.producttype = 'OnSale'
    ) saleprice
    where row_rank = 1

РЕДАКТИРОВАТЬ разделов по идентификатору (при условии, что ваш первичный ключ самый быстрый), раздел по цене удален

0 голосов
/ 30 сентября 2009
SELECT TOP 1 p.ProductName, pp.Price, pp.Date,
FROM product p
INNER JOIN productprice pp on ...
WHERE pp.date < @DateIn
ORDER BY pp.date DESC
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...