【问题标题】:How can I conditional join two tables to get results based on an evaluation (SQL Server)?如何根据评估(SQL Server)有条件地连接两个表以获取结果?
【发布时间】:2021-07-14 18:40:08
【问题描述】:

我的数据库中有两个表:

办公室

id       Department         Section       PositionID         
-------------------------------------------------------
1    |   DataCenter   |    Developer  |       10     
2    |   DataCenter   |    DBA        |       11     
3    |   DataCenter   |    SA         |       12     
4    |   DataCenter   |    HelpDesk   |       13     
5    |   DataCenter   |    DepHead    |       14
6    |   Produce      |    Stocker    |       19
7    |   Produce      |    Farmer     |       20

职位

id        PosName         OfficeID       Level         
-------------------------------------------------------
10    |  Senior Dev   |       1     |     1     
11    |  Senior DBA   |       2     |     1 
12    |  Senior SA    |       3     |     1 
13    |  Help Desk    |       4     |     2 
14    |  Supervisor   |       1     |     0
15    |  Junior Dev   |       1     |     2
16    |  Junior Dev   |       3     |     2
17    |  Junior DBA   |       2     |     2
18    |  Junior DBA   |       2     |     2
19    |  Junior DBA   |       2     |     2
20    |  Junior SA    |       1     |     2

如何根据部门和部门从职位中选择所有条目,但要高于他们的级别?我猜我需要加入某种经过评估的条件才能执行此操作。

例如,高级开发人员职位位于 1 级。因此,我希望将 2 级的两个初级开发人员职位与其分组。同样,三个 2 级初级 DBA 职位将与高级 DBA 职位相关联。最棘手的部分是获取数据中心中与主管(处于 0 级)相关联的所有职位。

我的最终目标是在网页中使用此查询,在该网页中,分配到某个职位的用户只能看到在他们下属以及在其部门/部门工作的用户。

所以最终查询结果可能看起来像这样:

Department      Section        ManagingPosition         Position        PositionID
-----------------------------------------------------------------------------------
DataCenter   | Developer  |      Senior Dev       |   Junior Dev   |       15    
DataCenter   | Developer  |      Senior Dev       |   Junior Dev   |       16    
DataCenter   | DBA        |      Senior DBA       |   Junior DBA   |       17    
DataCenter   | DBA        |      Senior DBA       |   Junior DBA   |       18   
DataCenter   | DBA        |      Senior DBA       |   Junior DBA   |       19    
DataCenter   | SA         |      Senior SA        |   Junior SA    |       20   
DataCenter   | DepHead    |      Supervisor       |   Junior Dev   |       15
DataCenter   | DepHead    |      Supervisor       |   Junior Dev   |       16
DataCenter   | DepHead    |      Supervisor       |   Junior DBA   |       17
DataCenter   | DepHead    |      Supervisor       |   Junior DBA   |       18
DataCenter   | DepHead    |      Supervisor       |   Junior DBA   |       19
DataCenter   | DepHead    |      Supervisor       |   Junior SA    |       20
DataCenter   | DepHead    |      Supervisor       |   Help Desk    |       13

到目前为止,我已经

SELECT
    O.Department,
    O.Section,
    O.Position AS ManagingPosition,
    P.PosName AS Position,
    P.PositionID
FROM
    Offices O
    INNER JOIN Positions P on O.PositionID = P.id

不过,我知道这是不正确的。查询这些表以获得我想要的结果的最佳方法是什么?我也可以修改这些表(添加列)以获得结果。感谢您的帮助!

编辑:

为澄清起见,职位表中的级别以级别 0 为最高,级别 2 为最低。所以 0 级应该能够看到更大的东西(即 1 级和 2 级),而 1 级应该只能看到 2 级。

【问题讨论】:

  • Bad Habits to Kick : Using table aliases like (a, b, c) or (t1, t2, t3)。 “A”不是官员,“B”也不是职位。 “O”和“P”将是更好的选择。
  • 这样的设计,不清楚哪个职位是其他职位的更高级别,所以需要一个新的列像“managerpositinId”来为每个职位分配一个经理,否则没有办法找到出
  • 您应该在 Positions 表中有另一列。像 ParentPositionId 这样的东西来知道谁在某个位置。
  • @Larnu,你是对的。这绝对是我应该做得更好的事情 - 感谢您让我保持一致!我继续更新我的帖子。
  • @eshirvana,对不够清晰表示歉意。数字越小,职位的级别越高。我也编辑了我的帖子以提高清晰度。我也会研究 managerpositionId 列的想法。谢谢!

标签: sql sql-server tsql join


【解决方案1】:

首先你需要添加一个列来定义每个位置的父位置。

然后一个选项是使用 CTE 递归 (https://www.sqlservertutorial.net/sql-server-basics/sql-server-recursive-cte/)

WITH PositionsCTE ( PositionID, ManagingPosition, Position, OfficeId, [Level])
AS
(   
    --starts with the very first level 
    SELECT
        id as PositionID, cast('' as varchar(50)) as ManagingPosition,
        PosName, OfficeId, [Level]
    FROM Positions 
    WHERE ParentId IS NULL -- (supervisor in this case)
    UNION ALL
    -- and then recursivity 
    SELECT
        p.id as PositionID, Pcte.Position as ManagingPosition,
        p.PosName, p.OfficeId, p.[Level]
    FROM Positions AS p
    INNER JOIN PositionsCTE Pcte ON p.ParentId = Pcte.PositionID
)
Select 
    o.Department,
    o.Section, 
    p.ManagingPosition,
    p.Position,
    p.PositionID
from Offices o
inner join PositionsCTE p on o.id = p.OfficeId;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-19
    • 1970-01-01
    • 2016-11-18
    相关资源
    最近更新 更多