mysql - 优化这个包含多个子查询的查询

标签 mysql sql

我很难在脑海中解决这个问题,需要一些帮助来弄清楚是否有更好的方法来产生相同的结果。

我们有 3 个表:stores、departments、sales。 每个商店可以有多个部门。 每个部门可以有很多销售。

我有一个查询,其中列出了每家商店并对相关销售额进行计数和求和。但是当我觉得它应该能够在 1 中完成时,操作是用 2 个子查询进行的。

这只是一个运行速度非常快的示例。在我正在构建的真实报告中,我发现我添加的每个后续子查询都会显着降低报告的整体性能。

SQL Fiddle

SELECT `name`,

@totalvalue := ( SELECT SUM(`price`) FROM `sales` WHERE `sales`.`department` IN (
  SELECT `id` FROM `departments` WHERE `departments`.`store`=`stores`.`id`
) ) AS `totalvalue`,

@totalsales := ( SELECT COUNT(*) FROM `sales` WHERE `sales`.`department` IN (
  SELECT `id` FROM `departments` WHERE `departments`.`store`=`stores`.`id`
) ) AS `totalsales`,

ROUND(@totalvalue / @totalsales,2) AS `averagesale`

FROM `stores`;

如何在子查询 1 中或通过连接生成 totalsalestotalvalue

非常感谢您提供的任何帮助。

最佳答案

您必须同时使用 GROUP BY 聚合函数和 JOIN 表:

SELECT st.name, SUM(s.price) totalvalue, COUNT(s.id) totalsales, ROUND(AVG(s.price),2) averagesale
FROM stores st
LEFT JOIN departments d ON d.store=st.id
LEFT JOIN sales s ON s.department=d.id
GROUP BY st.name

LEFT JOIN 因为无论是否有任何数据,你都想显示所有商店,否则你会使用 INNER JOIN。

此外,您不必自己计算平均值 - 它是内置函数。只要您不需要加权平均就足够了。

关于mysql - 优化这个包含多个子查询的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45206822/

相关文章:

php - MySql 查询通过保留最新的时间戳值来删除重复的行?

mysql - bool 字段作为唯一索引

java - 是否可以在不同物理服务器上的 oracle 数据库和 postgresql 数据库之间使用数据库链接

MySQL 如何通过 MAX(id) 选择 smth....WHERE userID = 某个数字 GROUP BY smth

mysql - Mysql/Mariadb必须在“选择”或“更新”中的列之前使用表名

php - 这个 SQL 查询有什么问题? (或者也许为什么 MySQL 不喜欢第六个字段?)

php - 使用php的Mysql选择查询结果为空行值

mysql - Hadoop Hive 查询从单独的表中选择和分组

mysql - 比较 MYSQL 子查询中的日期

sql - Django 模型 - 外键作为主键