mysql - 对于员工表中的每个员工,查找层次结构中直接和间接老板的数量

标签 mysql sql hierarchy

我得到了一个员工表,看起来像这样:

enter image description here

创建示例输入的查询。

CREATE TABLE employee(
    empId INTEGER,
    empName VARCHAR(20),
    mgrId INTEGER,
    salary DECIMAL(12,2)
);

INSERT INTO employee VALUES
(1, 'A', 2, 100),
(2, 'B', 4, 150),
(3, 'C', 4, 165),
(4, 'D', 7, 200),
(5, 'E', 6, 210),
(6, 'F', 7, 250),
(7, 'G', 7, 300),
(8, 'H', 6, 170);

链接到 SQL Fiddle:http://sqlfiddle.com/#!9/cd4be8

此示例数据会产生此层次结构。

enter image description here

每个员工都有一个直接上司。此外,所有比特定员工高级的员工都被称为他们的间接老板。 在给定的样本中,A的直接老板是B,C、D、E、F、G和H是A的间接老板。我需要找到两件事。

  1. 对于每个员工,查找比该员工高级的所有员工的数量(直接上司 + 间接上司的数量)。

预期输出:

+---------+-------+
| empName | total |
+---------+-------+
| A       |     7 |
| B       |     3 |
| C       |     3 |
| D       |     1 |
| E       |     3 |
| F       |     1 |
| G       |     0 |
| H       |     3 |
+---------+-------+
  • 对于每个员工,找到间接老板,使间接老板的工资至少是给定员工工资的两倍,但在间接老板中最低。
  • 预期输出:

    +---------+------+
    | empName | mgr  |
    +---------+------+
    | A       | D    |
    | B       | G    |
    | C       | NULL |
    | D       | NULL |
    | E       | NULL |
    | F       | NULL |
    | G       | NULL |
    | H       | NULL |
    +---------+------+
    

    解释:对于员工A(工资=100),工资至少双倍的间接老板是D(工资=200)、F(工资=210)和G(工资=300)。但由于 D 的工资是 D、F 和 G 中最低的,所以结果是 D。

    查找员工的下属人数很容易,但反之则非常棘手。任何帮助/提示将不胜感激。

    最佳答案

    我希望您会发现以下答案对您有所帮助,直到出现更优化的解决方案。

    第一步创建一个新 View ,记录员工的级别。在这种情况下,名为 G 的“老板”的值最小为 1。而每个级别的员工的排名都在增加,其中 A 的最高值为 4。该 View 是使用分层查询构建的 here。 .

    创建 View 后,通过对所有较高级别的员工求和来回答第一个问题。这是针对每个排名完成的,并且连接将信息带到最终 View 。

    第二个问题以更暴力的方式回答。执行自连接以产生员工和老板的所有可行组合。之后,将生成具有最低老板工资的行。

    --Creating a view with the level of the diagram
    CREATE VIEW MyCTEView 
    AS 
        WITH my_anchor AS (
            SELECT boss.[empId], boss.[empName], boss.[mgrId], 1 AS EmpLevel
            FROM [MySchema].[dbo].[employee] AS boss
            WHERE boss.[mgrId]=boss.[empId]
    
            UNION ALL
    
            SELECT Emp.[empId], Emp.[empName], Emp.[mgrId], EL.EmpLevel+1
            FROM [MySchema].[dbo].[employee] AS Emp
            INNER JOIN my_anchor as EL
            ON Emp.[mgrId] = EL.[empId]
            WHERE Emp.[mgrId]<>Emp.[empId]
            )
        SELECT * FROM my_anchor;
    
    
    --Answer to the first question
    SELECT A.[empName]
          ,temp.direct_and_indirect-1 AS your_total
    FROM [MySchema].[dbo].[MyCTEView] AS A
    LEFT JOIN (
    SELECT [EmpLevel],SUM(direct_subortinates) OVER(ORDER BY [EmpLevel]) AS direct_and_indirect
    FROM (SELECT COUNT([mgrId]) AS direct_subortinates,[EmpLevel]
                FROM [MySchema].[dbo].[MyCTEView] GROUP BY [EmpLevel])T) AS Temp
    ON Temp.[EmpLevel]=A.[EmpLevel]
    ORDER BY A.[empName]
    
    
    --Answer to the second question. Creating a CTE with all the viable combinations of employee and manager based on criteria.
    --Displaying the information for the minimum
    WITH cte AS (
    SELECT A.[empId] as emId
          ,A.[empName] as emName
          ,A.[salary] as emsalary
          ,A.[EmpLevel] as emLevel
          ,B.[empId] as bossId
          ,B.[empName] as bossName
          ,B.[salary] as bosssalary
          ,B.[EmpLevel] as bossLevel
      FROM [MySchema].[dbo].[MyCTEView] AS A
      INNER JOIN 
      [MySchema].[dbo].[MyCTEView] AS B
      ON A.empId<>B.empId AND A.[EmpLevel]>B.[EmpLevel] AND B.[salary]>=2*A.[salary]
      )
    SELECT tb1.emName, tb1.bossName 
    FROM cte AS tb1
      INNER JOIN
      (
        SELECT emName, MIN(bosssalary) MinSalary
        FROM cte
        GROUP BY emName
      )tb2
      ON  tb1.emName=tb2.emName
      WHERE tb1.bosssalary=tb2.MinSalary
    

    关于mysql - 对于员工表中的每个员工,查找层次结构中直接和间接老板的数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58852294/

    相关文章:

    mysql - 仅返回1条记录

    python - 如何解析多个层次结构下的 XML 文件?

    mysql - 将父记录设置为空,以便删除子记录 : howto?

    mysql - SQL JOINING,哪个是最好的连接

    sql - 从表中选择列名和值

    node.js - 使用 mongodb 和 nodejs 的类别层次聚合

    php - 我对任意深度层次数据集的嵌套集的替代方法 : Good or Bad?

    php 从 mysql 结果建立链接

    mysql - Eloquent Laravel 的问题

    mysql - 尝试在 MYSQL 中为当前月份创建 6 个月滚动