【问题标题】:How to use self join to filter the records in same table in SQL Server 2012SQL Server 2012如何使用自连接过滤同一张表中的记录
【发布时间】:2020-11-16 13:15:12
【问题描述】:

我有一张桌子,里面有员工和团队负责人。 我有以下数据

Declare @EMP AS TABLE(EmpID INT, EmpName VARCHAR(100),TeamLeadID INT)
INSERT INTO @EMP(EmpID, EmpName,TeamLeadID) VALUES
 (1,'Ramesh',5)
,(2,'Mahesh',3)
,(3,'Vijay',3)
,(4,'Varma',5)
,(5,'Raj',5)

我想列出所有员工以及他们的团队负责人 ID 和姓名。但是当employeeid = teamleadid时,teamleaderid和name应该为空。

结果应该如下。

EmpID   EmpName   TeamLeadID    TeamLeadName
1       Ramesh        5             Raj
2       Mahesh        3            Vijay
3       Vijay        NULL           NULL
4       Varma         5             Raj
5        Raj         NULL           NULL

代码如下。

SELECT E.EmpID,E.EmpName,TL.TeamLeadID,TL.EmpName AS TeamLeadName 
FROM @Emp E
LEFT JOIN @Emp TL ON E.TeamLeadID = TL.EmpID AND E.EmpID ! = TL.EmpID

有没有其他方法可以重写这段代码并获得更高的性能(主要是不使用Not equal to at E.EmpID ! = TL.EmpID)并且不使用CTE?

【问题讨论】:

  • 看来您应该修复数据。某人不能成为他们自己的领导者,因此用户3 不应该为TeamLeadID 提供3 的值;应该是NULL
  • 仅供参考,在您的示例数据中,您所有的员工都有姓名'Ramesh''Vijay''、'Varma'等是从哪里来的?
  • 为什么要强加不使用!=和CTE之类的条件?这两个都是 T-SQL 工具箱中的重要工具,而且它们本身都不会影响性能。在 SQL 中,您应该使用正确的工具正确解决您的问题,然后,如果性能是一个问题,您应该尝试调整您的解决方法。
  • @Larnu,抱歉数据已更正
  • 当前查询是否存在性能问题?执行计划是什么样的?请使用Paste the plan分享。

标签: sql-server tsql sql-server-2012


【解决方案1】:

如果你想避免 WHERE 子句中的 NOT EQUAL,你可以像这样在 SELECT 子句中移动你的“逻辑”:

SELECT E.EmpID,E.EmpName, 
      IIF(TL.TeamLeadID=E.EmpID,NULL,TL.TeamLeadID) AS TeamLeadID ,
      IIF(TL.EmpName=E.EmpName,NULL,TL.EmpName) AS TeamLeadName
FROM @Emp E
LEFT JOIN @Emp TL ON E.TeamLeadID = TL.EmpID 

它是否会更有性能很难说。这取决于您的数据,主要是受影响的记录和团队负责人的数量。如果你没有大量的数据,差异应该是荒谬的

【讨论】:

    【解决方案2】:

    另一种选择是在 SELECT 语句中使用 CASE WHEN 子句

    SELECT E.EmpID,E.EmpName,
    CASE
        WHEN E.EmpID = TL.TeamLeadID
            THEN NULL
        ELSE TL.TeamLeadID
    END AS TeamLeadID
    ,CASE
        WHEN E.EmpID = TL.TeamLeadID
            THEN NULL
        ELSE TL.EmpName
    END AS TeamLeadName 
    FROM @Emp E
    LEFT JOIN @Emp TL ON E.TeamLeadID = TL.EmpID 
    

    【讨论】:

      猜你喜欢
      • 2012-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-17
      • 2016-11-27
      • 1970-01-01
      • 2013-11-07
      相关资源
      最近更新 更多