jwalls91
jwalls91

Reputation: 351

How to select rows with related values?

I have a table "company" with data like follows containing employees and their companies:

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

I am trying to display rows where if the Parent Co ID value is in the Company ID, then show both rows for that employee. So basically select employees that are in both the parent company and the sub company and show both of those rows.

I've tried

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

but this only returns the row where the CompanyID value matches and I'm not sure how to also include that second row also.

My desired output for the sample above would be:

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

As from the result above, Company A.1 is a sub company of A, and same with company E and E.2. I am trying to select employees that are in both the main company and sub company and therefore need to refer to the ParentCoID and the CompanyID columns.

Upvotes: 2

Views: 535

Answers (5)

Stu
Stu

Reputation: 32614

Here's a slightly different approach using a simple window function and a self-join and will likely be performant given a clustered index on (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

Upvotes: 1

Anton Grig
Anton Grig

Reputation: 1719

A recursive CTE is useful in querying hierarchical data.

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

Upvotes: 1

smpa01
smpa01

Reputation: 4346

Using 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) 
    

Upvotes: 1

Rinkal Rohara
Rinkal Rohara

Reputation: 352

Please try this: Updated the query.

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)

Upvotes: 1

Sam Ware
Sam Ware

Reputation: 127

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

Upvotes: 1

Related Questions