我在Postgresql数据库表中有带有以下列的产品:
standard_price -- Price of product
promo_price -- Price of product in sale
promo_date_from -- Sale is valid from
promo_date_to -- Sale is valid to
任务是按当前价格订购产品。当今天在promo_date_from和promo_date_to内时,当前价格为promo_price;否则,当前价格为standard_price。
一个可能的解决方案是这样的:
SELECT * FROM products
ORDER BY
CASE WHEN promo_date_from <= '2020-02-24'::date AND '2020-02-24'::date <= promo_date_to THEN
promo_price
ELSE
standard_price
END;
但是,此解决方案相当慢,我不知道如何加快速度?是否有任何一种索引,在这种情况下或诸如视图,函数等更好的方法中可能有用?
主要问题是,我认为查询不是“静态”查询-它取决于日期参数,该参数是查询的一部分(上例中为“ 2020-02-24”)。
谢谢您的帮助。
更新:
从下面的评论中我有一个主意,是否可以做这样的事情:
在standard_price
,promo_price
,promo_date_from
和promo_date_to
上将有索引。
在这些查询上方使用索引会很快:
query_promo = SELECT *, promo_price AS current_price FROM products WHERE '2020-02-24'::date BETWEEN promo_date_from AND promo_date_to ORDER BY promo_price
和
query_standard = SELECT *, standard_price AS current_price FROM products WHERE NOT('2020-02-24'::date BETWEEN promo_date_from AND promo_date_to) ORDER BY standard_price
上面的查询给了我两个带有空交集的排序集,因此使用UNION ALL是安全的。现在,最好的优化方法是使用某种合并排序算法来合并它们。
因此,问题是,Postgresql中是否有东西可以将这两个排序的集合合并为一个集合(通过current_price
列)?最后在那之后应用分页的限制/偏移量吗?
答案 0 :(得分:0)
CREATE OR REPLACE FUNCTION prices (d DATE DEFAULT now())
RETURNS TABLE (id int, name VARCHAR, price decimal(12,2)) AS $$
SELECT
id,
name,
CASE WHEN $1 BETWEEN promo_date_from AND promo_date_to
THEN promo_price
ELSE standard_price
END
FROM your_table
$$ LANGUAGE SQL;
日期默认为当前日期,或者您可以将值date作为参数:
select * from prices() order by price;
select * from prices('2020-02-02') order by price;