I have a query to get all penalty data with latest prices. In prices table there are many prices related to a product. To take the valid price I need to get the latest price. Here is the query.
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;
My question: Is there any way to replace the nested query here in order to take only one latest date from the product_price table or is it ok to use nested queries.
2
Answers
You can use
DISTINCT ON
to keep the first row of each group. For example, you can do:To retrieve data for a single given product, a
LATERAL
subquery is typically fastest. Most flexible, too.See:
Be sure to have an index on
product_price (product_id, valid_from)
, or some refined version, depending on undisclosed details. A PK index onproduct(id)
can be assumed.Retrieving most or all products at once is typically faster with a different query style. But your given query clearly indicates a single product.
Subtle differences
Your original returns all related rows from
product_price
with the latestvalid_from
. My query always picks a single one. Typically,(product_id, valid_from)
should be definedUNIQUE
to make this unambiguous.Your original also returns no row from
product_price
where any related row withvalid_from IS NULL
exists. Null sorts on top in descending sort order and the subsequent join conditionvalid_from = null
eliminates all rows. You would have aNOT NULL
constraint or at least useDESC NULLS LAST
in the query to sort null values last. See:(And you should declare all of that in the question.)