如何通过聚合列过滤非聚合查询结果?
How to filter nonaggregated query results by an aggregated column?
我正在创建价格比较服务。一个 Site
的产品与一个或多个 Sites
的产品进行比较。使用 ProductMatch
table:
将产品从一个 Site
匹配到另一个
给定以下查询以提取产品及其匹配项:
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 中表现不佳
在 CTE
中使用 MIN()
window 函数将被过滤:
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
我正在创建价格比较服务。一个 Site
的产品与一个或多个 Sites
的产品进行比较。使用 ProductMatch
table:
Site
匹配到另一个
给定以下查询以提取产品及其匹配项:
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 中表现不佳
在 CTE
中使用 MIN()
window 函数将被过滤:
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