我有一张巨大的卖桌。 在此表中,我们有产品和销售日期。 我想为每个产品找到最近的5个销售。 它很容易找到查询,但我想找到一个快速的? 例如:
with foo as
(select RANK() OVER(PARTITION BY product ORDER BY sale_date DESC) RK, p.*
from sell p)
select * from foo where rk < 6
但是这个查询会进行全表扫描并对每一行进行排序。 所以它不是一个有效的查询。
有什么想做的更好吗?
非常感谢
答案 0 :(得分:1)
此查询:
with foo as (
select RANK() OVER (PARTITION BY product ORDER BY sale_date DESC) as RK,
p.*
from sell p
)
select *
from foo
where rk < 6;
可以利用sell(product, sale_date)
上的索引。
答案 1 :(得分:0)
您必须在某个时刻扫描整个表格以满足功能要求:
我想为每种产品找到最后一次销售。
你不会找到一种更有效的方法,使用窗口函数如RANK()
但严格来说我会使用ROW_NUMBER()
来满足该要求,因为RANK()
或{{1}可以重复值(因此您可能会在产品上获得超过5行)。
如果您可以按日期限制子查询的范围,例如忽略超过6个月的所有销售,然后您可能会避免表扫描。但根据您对需求的描述,这似乎并不适用。请注意,如果查询优化器认为您需要表的大部分而不值得使用索引,则可以选择表扫描。
DENSE_RANK()
我避免使用“化妆品CTE”( CTE用作替代派生表子查询)。