将子查询转换为MySQL的JOIN语句?
以下是我当前的查询:将子查询转换为MySQL的JOIN语句?,mysql,sql,Mysql,Sql,以下是我当前的查询: SELECT prod.id, prod.title, prod.price, prod.status, (SELECT COUNT(*) FROM payments WHERE product = prod.id AND ( vendor = '1' AND credited = 'Vendor' )
SELECT prod.id,
prod.title,
prod.price,
prod.status,
(SELECT COUNT(*)
FROM payments
WHERE product = prod.id
AND ( vendor = '1'
AND credited = 'Vendor' )
AND ( status = 'Completed'
OR status = 'Pending'
OR status = 'Canceled_Reversal' )) AS sales,
(SELECT SUM(price)
FROM payments
WHERE product = prod.id
AND ( vendor = '1'
AND credited = 'Vendor' )
AND ( status = 'Completed'
OR status = 'Pending'
OR status = 'Canceled_Reversal' )) AS revenue
FROM products prod
WHERE member = '1'
AND status != 'Deleted'
AND status != 'Blocked'
现在我在主查询中使用了两个子查询
有没有办法改用JOIN语句或简化查询以加快查询速度
还是没有什么能让它快得多?我会写得简单一点:
SELECT p.id, p.title, p.price, p.status,
(SELECT COUNT(*)
FROM payments pa
WHERE pa.product = p.id AND
pa.vendor = p.member AND
pa.credited = 'Vendor' AND
pa.status IN ('Completed','Pending', 'Canceled_Reversal')
) AS sales,
(SELECT SUM(pa.price)
FROM payments pa
WHERE pa.product = p.id AND
pa.vendor = p.member AND
pa.credited = 'Vendor' AND
pa.status IN ('Completed','Pending','Canceled_Reversal')
) AS revenue
FROM products p
WHERE p.member = 1 AND
p.status NOT IN ('Deleted', 'Blocked');
这基本上是您的查询,具有更简单的别名和逻辑
使用付款(产品、供应商、信用、状态、价格)
索引,这可能比其他方法更快
另一种选择是:
SELECT p.id, p.title, p.price, p.status,
COUNT(pa.product) as sales
SUM(pa.price) as revenue
FROM products p LEFT JOIN
payments pa
ON pa.product = p.id AND
pa.vendor = p.member AND
pa.credited = 'Vendor' AND
pa.status IN ('Completed', 'Pending', 'Canceled_Reversal')
WHERE p.member = 1 AND
p.status NOT IN ('Deleted', 'Blocked')
GROUP BY p.id, p.title, p.price, p.status;
但是,子查询可能会更快。将连接与聚合一起使用:
SELECT
prod.id,
prod.title,
prod.price,
prod.status,
COALESCE(t.sales, 0) AS sales,
COALESCE(t.revenue, 0) AS revenue
FROM products prod
LEFT JOIN
(
SELECT
product,
COUNT(*) AS sales,
SUM(price) AS revenue
FROM payments p
WHERE vendor = '1' AND credited = 'Vendor' AND
status IN ('Completed', 'Pending', 'Canceled_Reversal')
GROUP BY product
) t
ON t.product = prod.id;
请注意,我们在这里使用左连接,以满足产品
表中的某些产品在付款
表中甚至可能没有任何匹配数据的可能性。在这种情况下,我们还使用COALESCE
报告销售额和收入的零值
上述别名为t
的子查询可能可以使用以下索引进行优化:
payments (product, vendor, credit, status, price)
谢谢,效果很好!子查询通常比连接更快吗?@ShadowAccount。有时候,没有硬性规定。真正的比较是聚合,避免外部聚合通常有利于性能。