使用where子句中的select max()函数改进Sql查询

时间:2009-09-30 19:01:47

标签: sql sql-server sql-server-2005 tsql

此查询的目的是带回产品及其销售产品的价格,价格应该从最接近但不等于传递日期的日期开始,基本上是最近可用的价格。每天都没有价格记录。在where子句中使用聚合select语句有点不对劲。有一个更好的方法吗?也许在加入标准?

        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'

实际查询有点复杂,但这基本上就是问题。感谢您的投入。

修改 将返回多个产品

修改 我正在试验@Remus Rusanu和@ km的建议(虽然@Remus Rusanu删除了他的)这三个,包括我原来的,在性能方面似乎差不多。我试图决定一个人是否以其他一些无形的方式提供优惠,即维护,自我记录等,因为这将由其他人维持。再次感谢。

3 个答案:

答案 0 :(得分:5)

试试这个:

;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'

编辑基于OP的评论:

我认为CTE上面的查询将与derived table version from @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 :(得分:1)

这是窗口功能的工作吗?

    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
按ID分类

编辑分区(假设您的主键最快),价格已删除

答案 2 :(得分:0)

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