根据当前日期查询的条件订单

时间:2020-02-24 21:43:51

标签: postgresql date

我在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”)。

谢谢您的帮助。

更新

从下面的评论中我有一个主意,是否可以做这样的事情:

  1. standard_pricepromo_pricepromo_date_frompromo_date_to上将有索引。

  2. 在这些查询上方使用索引会很快:

    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

  3. 上面的查询给了我两个带有空交集的排序集,因此使用UNION ALL是安全的。现在,最好的优化方法是使用某种合并排序算法来合并它们。

因此,问题是,Postgresql中是否有东西可以将这两个排序的集合合并为一个集合(通过current_price列)?最后在那之后应用分页的限制/偏移量吗?

1 个答案:

答案 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;