【问题标题】:How to select rows with related values?如何选择具有相关值的行?
【发布时间】:2021-07-31 16:31:29
【问题描述】:

我有一个表“公司”,其中包含如下数据,其中包含员工及其公司:

EmployeeID        EmployeeName           CompanyName            CompanyID           ParentCoID 
------------------------------------------------------------------------------------------------

100                John                      A                       500                 NULL
100                John                      A.1                     600                 500
250                Paul                      B                       800                 NULL
250                Paul                      ABC                     2000                NULL
350                Joe                       D                       1000                5000
600                Tom                       E                       700                 NULL
600                Tom                       E.2                     1500                700

我正在尝试显示父公司 ID 值在公司 ID 中的行,然后显示该员工的两行。所以基本上选择母公司和子公司的员工并显示这两行。

我试过了

SELECT *
FROM company
WHERE CompanyID IN (SELECT ParentCoID FROM company)

但这只会返回 CompanyID 值匹配的行,我不确定如何也包括第二行。

我对上面示例的期望输出是:

EmployeeID        EmployeeName           CompanyName            CompanyID           ParentCoID 
------------------------------------------------------------------------------------------------
    
100                John                      A                       500                 NULL
100                John                      A.1                     600                 500
600                Tom                       E                       700                 NULL
600                Tom                       E.2                     1500                700

由上图可知,A.1 公司是 A 的子公司,与 E 公司和 E.2 公司相同。我正在尝试选择同时在主公司和子公司中的员工,因此需要参考 ParentCoID 和 CompanyID 列。

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:
    SELECT * FROM company
    WHERE EmployeeID IN (SELECT EmployeeID FROM company WHERE CompanyID IN (SELECT ParentCoID FROM company)
    

    【讨论】:

      【解决方案2】:

      请试试这个: 更新了查询。

      SELECT * FROM company c
      WHERE CompanyID IN (SELECT ParentCoID FROM company c2 WHERE c2.EmployeeID = c.EmployeeID) OR ParentCoID IN (SELECT CompanyID FROM company c3 WHERE c3.EmployeeID = c.EmployeeID)
      

      【讨论】:

      • 我相信这行得通,但我忘了在上面提到它还需要确保它也与同一员工匹配。因为另一名员工可能拥有与另一名员工相同的 CompanyID
      【解决方案3】:

      使用EXISTS

      SELECT a.*
      FROM   company a
      WHERE  EXISTS (SELECT b.parentcoid
                     FROM   company b
                     WHERE  a.companyid = b.parentcoid
                            AND a.employeeid = b.employeeid)
      UNION ALL
      SELECT c.*
      FROM   company c
      WHERE  EXISTS (SELECT d.companyid
                     FROM   company d
                     WHERE  d.companyid = c.parentcoid
                            AND d.employeeid = c.employeeid) 
          
      

      【讨论】:

        【解决方案4】:

        递归 CTE 在查询分层数据时很有用。

        with cte As (
        select * from company c
        Where ParentCoID is null and CompanyID = Any(Select ParentCoID From company Where EmployeeID=c.EmployeeID)
        union all
        select c.*
        from cte p inner join company c On (p.CompanyID=c.ParentCoID And p.EmployeeID=c.EmployeeID)
        )
        select * From cte order by EmployeeID, CompanyID, ParentCoID
        

        【讨论】:

          【解决方案5】:

          这是一种稍微不同的方法,它使用简单的window function 和自联接,并且在给定 (EmployeeId,ParentCoId) 上的聚集索引的情况下可能会很高效。

          with e as (
              select EmployeeID,ParentCoID CoId, 
                  Sum(case when ParentCoID is null then 1 end ) over(partition by EmployeeID) IsSub
              from Company
          )
          select c.* 
          from e 
          join Company c on c.EmployeeID=e.EmployeeID
          where (e.CoId=c.CompanyID or e.CoId=c.ParentCoID)
          and e.CoId is not null and e.IsSub=1
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-03-03
            • 1970-01-01
            • 1970-01-01
            • 2021-02-06
            • 1970-01-01
            • 2022-11-23
            • 1970-01-01
            相关资源
            最近更新 更多