Postgres中基于最后一个非空值的唯一约束

时间:2018-10-12 05:14:00

标签: sql postgresql database-design concurrency constraints

我有一个如下表:create table prices_history (id0 serial primary key, product_id0 int, time_added timestamptz, listed_price numeric)

当该price的{​​{1}}与我要的价格不同时,我只想将特定的product_id0的新max(time_added)插入表格中插入。当前,假设我想为ID为product_id0的产品插入价格9.50,我将通过以下查询进行操作:

101

是否有更好的查询来解决此问题?

我在Ubuntu 16.04 LTS上使用Postgres insert into prices_history (product_id0, time_added, price) ( select 101, NOW(), 9.50 where not exists ( select * from ( select distinct on (product_id0) * from prices_history order by product_id0, time_added desc ) x where product_id0=101 and listed_price=9.50 ) ) returning id0

1 个答案:

答案 0 :(得分:0)

我发现使用WHERE NOT EXISTS而不是使用LEFT JOIN..WHERE NULL来做批量插入。这涉及对我要插入的数据进行左联接,选择旧表中没有匹配数据的数据。在以下示例中,说我有以下定价数据(表示为JSON):

[{price: 11.99, product_id0:2},
 {price: 10.50, product_id0:3},
 {price: 10.00, product_id0:4}]

以下查询将插入此数据的子集(如果其中任何一个是新信息):

insert into prices_history (product_id0, time_added, price)
(
   select new_product_id0, new_time_added, new_price from
     (select unnest(array[11.99, 10.50, 10.00]) as new_price, unnest(array[2,3,4]) as new_product_id0, now() as new_time_added) new_prices left join
     (select distinct on (product_id0) * from prices_history order by product_id0, time_added desc) old_prices 
   on old_prices.product_id0 = new_prices.new_product_id0 and old_prices.listed_price= new_prices.new_price 
   where old_prices.product_id0 is null and old_prices.listed_price is null
) returning id0

此新查询似乎在当前部署中运行良好。