如何按汇总列过滤非汇总查询结果?

时间:2020-02-19 15:36:57

标签: mysql sql mysql-8.0

我正在创建价格比较服务。将来自一个Site的产品与来自一个或多个Sites的产品进行比较。使用Site表将产品从一个ProductMatch匹配到另一个:

UML Diagram

给出以下查询以提取产品及其匹配项:

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;

如何过滤价格(p1.price)低于竞争对手最低价格(MIN(p2.price))的产品?

使用子查询,这是我的处理方式:

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
);

是否可以简化此查询以不使用子查询?

我的担忧:

  • 在子查询中重复完全相同的联接感觉很奇怪
  • 我担心较大数据集上的子查询的性能
  • 子查询在我的ORM中表现不佳

1 个答案:

答案 0 :(得分:1)

MIN()中具有CTE窗口功能,该功能将被过滤:

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