我有一个查询,要获取所有带有最新价格的罚款数据。价格表中有许多与产品相关的价格。要获取有效价格,我需要获取最新价格。这是查询。
SELECT *
FROM product
LEFT JOIN product_price productPrice
ON product.id = productPrice.product_id
AND productPrice.valid_from =
(SELECT valid_from FROM product_price
WHERE product_price.is_active = true AND valid_from <= now()
ORDER BY valid_from DESC LIMIT 1)
WHERE product.id = 1;
我的问题:是否有任何方法可以替换此处的嵌套查询,以便仅从 Product_price 表中获取一个最新日期,或者是否可以使用嵌套查询。
您可以使用
DISTINCT ON
保留每组的第一行。例如,您可以这样做:
select distinct on (p.id) *
from product p
left join product_price pp on p.id = pp.product_id
and pp.valid_from <= now() and pp.is_active = true
where p.id = 1
order by p.id, pp.valid_from desc
要检索单个给定产品的数据,
LATERAL
子查询通常是最快的。也最灵活。
SELECT *
FROM product p
LEFT JOIN LATERAL (
SELECT *
FROM product_price pp
WHERE pp.product_id = p.id
AND pp.is_active
AND pp.valid_from <= now()
ORDER BY pp.valid_from DESC
LIMIT 1
) ON true
WHERE p.id = 1;
参见:
使用不同的查询方式一次检索大多数或所有产品通常会更快。但您给出的查询清楚地表明了单个产品。
您的原始数据返回来自 product_price
的
所有相关行以及最新的
valid_from
。我的查询总是选择一个。通常,应将 (product_id, valid_from)
定义为 UNIQUE
以使其明确。
您的原始版本还从 product_price
返回
无行,其中存在任何与
valid_from IS NULL
相关的行。空值按降序排列在顶部,随后的连接条件 valid_from = null
会消除所有行。您将有一个 NOT NULL
约束,或者至少在查询中使用 DESC NULLS LAST
对空值进行最后排序。参见:
(你应该在问题中声明所有这些。)