I'm creating a price comparison service. Products from one Site
are compared to products from one or more Sites
. Products are matched from one Site
to another using a ProductMatch
table:
Given the following query to extract products, together with their matches:
SELECT
p1.id AS p1_id, p1.name AS p1_name, p1.price AS p1_price,
p2.id AS p2_id, p2.name AS p2_name, p2.price AS p2_price,
m.time
FROM Product p1
LEFT JOIN ProductMatch m ON m.fromProduct_id = p1.id
LEFT JOIN Product p2 ON m.toProduct_id = p2.id
WHERE p1.site_id = 1;
How can I filter products whose price ( p1.price
) is lower than the minimum competitor price ( MIN(p2.price)
)?
Using subqueries, here's how I would do it:
SELECT
p1.id AS p1_id, p1.name AS p1_name, p1.price AS p1_price,
p2.id AS p2_id, p2.name AS p2_name, p2.price AS p2_price,
m.time
FROM Product p1
LEFT JOIN ProductMatch m ON m.fromProduct_id = p1.id
LEFT JOIN Product p2 ON m.toProduct_id = p2.id
WHERE p1.id IN (
SELECT x.id FROM (
SELECT _p1.id, _p1.price
FROM Product _p1
JOIN ProductMatch _m ON _m.fromProduct_id = _p1.id
JOIN Product _p2 ON _m.toProduct_id = _p2.id
WHERE _p1.site_id = 1
GROUP BY _p1.id
HAVING _p1.price < MIN(_p2.price)
) x
);
Is it possible to simplify this query to not use subqueries?
My concerns:
With MIN()
window function inside a CTE
which will be filtered:
WITH cte AS (
SELECT
p1.id AS p1_id, p1.name AS p1_name, p1.price AS p1_price,
p2.id AS p2_id, p2.name AS p2_name, p2.price AS p2_price,
m.time,
MIN(p2.price) OVER (PARTITION BY p1.id) AS min_price
FROM Product p1
LEFT JOIN ProductMatch m ON m.fromProduct_id = p1.id
LEFT JOIN Product p2 ON m.toProduct_id = p2.id
WHERE p1.site_id = 1
)
SELECT
p1_id, p1_name, p1_price,
p2_id, p2_name, p2_price,
time
FROM cte
WHERE p1_price < min_price
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.