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:
- it feels weird to repeat the exact same joins in the subquery
- I have concerns about the performance of subqueries on larger data sets
- subqueries don't play very well with my ORM

 
    