mysql - 计算已知深度的层次结构中的值

标签 mysql sql

我必须从 2 个表中查询一些派生值。它们的简化结构如下:

用户

用户有一个 ID 和一个父列,该列表示其父级的 ID。每个用户还有一个佣金值,表示他们从本行员工那里获得的销售额百分比。

只有员工才能进行销售,该信息记录在下表中

+------------------------------------+
| ID Name          Parent Commission |
+------------------------------------+
| 1  SeniorManager NULL   5          |
| 2  Manager       1      10         |
| 3  Employee1     2      13         |
| 4  Employee2     2      12         |
+------------------------------------+

销售

此表记录通过 ID 链接的员工的销售额。它记录销售金额以及销售时间。

+---------------------------+
| user_id amount created_at |
+---------------------------+
| 3       100    2014-01-16 |
| 3       120    2014-01-16 |
| 3       110    2014-01-16 |
+---------------------------+
<小时/>

从系统的其他部分,我知道给定用户 ID 的用户的深度。在实际系统中,有7个固定级别,但为了问题起见,我在这里简化了它。

我试图编写的查询是:给定高级经理的 ID 和日期范围,显示他手下的经理列表、这些经理的总佣金以及该经理的预期佣金。因此,鉴于上述数据,人们可以预期:

+--------------------------------------------+
| Name    Sales ManagerCommission Commission |
+--------------------------------------------+
| Manager 330   33.30             16.65      |
+--------------------------------------------+

到目前为止我的查询是:

SELECT
    users.name AS Name,
    SUM(sales.amount) AS Sales,
    SUM(sales.amount) * (users.commission/100) AS ManagerCommission
FROM
    users
LEFT JOIN users AS employees
    ON employees.parent = users.id
LEFT JOIN sales
    ON sales.id = employees.id AND
    sales.created_at BETWEEN DATE(?) AND DATE(?)
WHERE
    users.parent = ?
GROUP BY
    users.name

我不确定如何获取按经理而不是员工分组的佣金的最后一列值。另外一个问题是,有没有办法重用在 select 语句中使用了两次的 SUM(sales.amount) 。我宁愿不要两次计算完全相同的值。我计划为每个已知深度编写 7 个查询。有没有更有效的方法来做到这一点?

最佳答案

为每个管理级别添加一个连接:-

SELECT
    senior_manager.name AS Name,
    SUM(sales.amount) AS Sales,
    SUM(sales.amount * manager.commission/100) AS ManagerCommission,
    SUM(sales.amount) * (senior_manager.commission/100) AS SeniorManagerCommission
FROM
    users AS senior_manager
LEFT JOIN users AS manager
    ON manager.parent = senior_manager.id
LEFT JOIN users AS employees
    ON employees.parent = manager.id
LEFT JOIN sales
    ON sales.id = employees.id AND
    sales.created_at BETWEEN DATE(?) AND DATE(?)
WHERE
    senior_manager.id = ?
GROUP BY
    senior_manager.name

SQL fiddle :-

http://www.sqlfiddle.com/#!2/2cfffe/4

关于mysql - 计算已知深度的层次结构中的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21156846/

相关文章:

php - 触发两个表以获取主键(自动增量)到第三个链接表mysql

纳税年度 7 月至 6 月的 SQL 累计总数

sql - GROUP BY HAVING NOT不会产生错误的结果

php - 如何限制 PHP While 循环的输出?

mysql - 为什么从 SQL 查询中删除 GROUP BY 语句时会收到此错误消息?

php - 多个搜索词的搜索查询

php - 防止 SQL 注入(inject)的建议

mysql - Tomcat 7 JDBC 池在故障转移期间耗尽并且无法恢复

php - mySQL中如何将一批数据添加到一批数据中?

mysql - 表索引建议