SQL查询按区域返回***经理

Posted

技术标签:

【中文标题】SQL查询按区域返回***经理【英文标题】:SQL query to return top line manager by area 【发布时间】:2018-05-18 06:42:15 【问题描述】:

我们正在尝试使用站点的高级经理(将其视为部门或成本中心)填充我们的用户表,以帮助定义站点的所有者。

EG:

在上面的示例中,我们希望返回员工“1002”以更新 site = '123' 的所有记录中的“所有者”

我们遇到的困难是站点内有 90,000 条员工记录和大量管理结构。可以是 1 级管理,也可以是 5 级...

我是 SQL 新手,我很困惑。我什至不确定这是否可能。

有什么建议吗?

【问题讨论】:

从您的数据集示例中,是否可以肯定地说,Site 中的最大数字 EmployeeID 将具有 LineManager 作为 OwnerSite 根据您的示例,是否会将 1103 作为站点 567 的所有者返回?或者是否需要 1103 的员工记录与 56​​7 的站点不同?您的选择标准不是很清楚,并且对如何设计查询以返回您想要的结果有很大影响。 抱歉,1234 & 2345 & 3456 & 5678 会在所有者处退回 1002 【参考方案1】:

网站所有者的定义似乎是:

a) 是站点内的直线经理,并且 b) 在同一个站点内没有不同的站点管理员

将其转换为 SQL:

update employee a set Owner = (
    select EmployeeId from employee b where b.Site = a.Site 
        and exists (select 1 from employee c where c.Site = b.Site and c.LineManager = b.EmployeeId)
        and not exists (select 1 from employee d where d.Site = b.Site and d.EmployeeId = b.EmployeeId and d.LineManager <> b.EmployeeId)
)

请看看这个定义是否有意义,并由企业来执行。我假设 EmployeeID 没有欺骗。

【讨论】:

我可以定义的最简单的方法是存在的第一个直线经理不共享相同的站点编号。 这不依赖于组织。图表,因此如果事情发生变化,这可能是一个不稳定的假设。此外,您的样本没有时间戳,您将如何确定“第一个”?按分钟。 ID?如果他们被解雇了,一个新的 ID 比下属高怎么办? 我们的想法是使用一个工具来查询数据,并在我们从 SAP 中提取的数据处理完毕后,每晚进行写入。数据不断变化,但我总是必须有一个直线经理。该数字用于关系,而不是最高数字获胜。我们的组织结构有点花哨,但每个员工都有一位直线经理。【参考方案2】:

这是我用来创建答案的一些测试数据(为了便于阅读,我稍微重命名了几列,添加了另一条记录来演示功能):

CREATE TABLE #test (EmployeeID INT, SiteID INT, LineManagerID INT, OwnerID INT)
INSERT INTO #test
    (
        EmployeeID
        ,SiteID
        ,LineManagerID
        ,OwnerID
    )
VALUES
    (
        1234  -- EmployeeID
        ,123 -- SiteID
        ,2345 -- LineManagerID
        ,NULL -- OwnerID
    ),
    (
        2345  -- EmployeeID
        ,123 -- SiteID
        ,3456 -- LineManagerID
        ,NULL -- OwnerID
    ),
    (
        3456  -- EmployeeID
        ,123 -- SiteID
        ,5678 -- LineManagerID
        ,NULL -- OwnerID
    ),
    (
        5678  -- EmployeeID
        ,123 -- SiteID
        ,1002 -- LineManagerID
        ,NULL -- OwnerID
    ),
    (
        1002  -- EmployeeID
        ,567 -- SiteID
        ,1103 -- LineManagerID
        ,NULL -- OwnerID
    ),
    (
        1103  -- EmployeeID
        ,568 -- SiteID
        ,6669 -- LineManagerID
        ,NULL -- OwnerID
    )

然后您的UPDATE 将使用递归 CTE 来计算每个 SiteID 的顶部 LineManagerID。

;WITH UserCTE
     AS (SELECT EmployeeID,
                SiteID,
                LineManagerID,
                0 AS [Level],
                NULL AS mgrEmpID
         FROM   #test

         UNION ALL

         SELECT usr.EmployeeID,
                usr.SiteID,
                usr.LineManagerID,
                mgr.[Level] + 1,
                mgr.EmployeeID AS mgrEmpID
         FROM   #test AS usr
         INNER JOIN UserCTE AS mgr ON usr.LineManagerID = mgr.EmployeeID AND usr.SiteID <> mgr.SiteID
         WHERE  usr.LineManagerID IS NOT NULL
         )
UPDATE t
SET t.OwnerID = u.mgrEmpID
FROM #test t
LEFT JOIN UserCTE u ON t.SiteID = u.SiteID AND u.[Level] = 1

这是UPDATE之后的表格:

EmployeeID  SiteID  LineManagerID   OwnerID
1234        123     2345            1002
2345        123     3456            1002
3456        123     5678            1002
5678        123     1002            1002
1002        567     1103            1103
1103        568     6669            NULL

【讨论】:

太棒了,查询返回了我需要的结果。我将复制一份数据库并试一试。谢谢你的智慧:)

以上是关于SQL查询按区域返回***经理的主要内容,如果未能解决你的问题,请参考以下文章

经典面试题-大厂SQL题目

力扣570(MySQL)-至少有5名直接下属的经理(简单)

c# sql双数据表按条件查询输出记录

为啥 SQL 查询的结果没有按我期望的顺序返回?

pl/sql 查询以通过 deptno 查找经理名称

SQL 查询以获取每个经理下的员工的递归计数