选择父级和子级记录。

6
如何选择一家公司和其子公司的所有员工?
使用 SQL Server 2008。
员工资料:
Id | Name | CompanyId  

公司

Id | Name | ParentCompanyId  

示例:

1 微软 0

2 微软印度 1

3 微软西班牙 1

我有以下查询,它只返回来自微软而不是来自微软印度和西班牙的员工。

SELECT Id, Name FROM Employee WHERE CompanyId=1

我不擅长SQL。请帮我解决这个问题。


1
你可以使用递归CTE - Tim Schmelter
1
很奇怪你只是点了“踩”按钮而没有尝试查询。为什么不试试呢,你会得到结果的。但如果你要提供一个母公司ID,那就是另一回事了。我回答了你在这里提出的问题。 - LiaqatG
1
@LiaqatG,我已经点赞了。不确定是谁踩了你的回答,请核实一下,虽然你的回答可能不准确;) 无论如何,其他人的踩让你少了2分,我的点赞让你多了10分,总共为你增加了8分。 - Billa
@TimSchmelter,我认为Union All帮助我简化了操作,并且我发现它与CTE一起使用。总的来说,我想Union ALL将是完美的选择。 - Billa
3个回答

8
使用通用表达式(CTE)构建公司层次结构,然后将其与员工表连接起来。
with CompanyHierarchy as
(
  select Id
  from Company
  where Id = 1
  union all
  select c.Id
  from Company c
    inner join CompanyHierarchy ch on c.ParentCompanyId = ch.Id
)
select e.*
from CompanyHierarchy ch
  inner join Employees e on ch.Id = e.CompanyId

点此查看带演示的SQL Fiddle.

如果您想将语句参数化,也可以在CTE的锚定部分替换一个CompanyId变量:

with CompanyHierarchy as
(
  select Id
  from Company
  where Id = @CompanyId
  union all
  select c.Id
  from Company c
    inner join CompanyHierarchy ch on c.ParentCompanyId = ch.Id
)
select e.*
from CompanyHierarchy ch
  inner join Employees e on ch.Id = e.CompanyId

SQL Fiddle演示链接,现在增加了层次结构级别。


由于互联网的特性,SQL Fiddle链接已经失效。 - The Fluffy Robot

2
SELECT 
   employee.name,
   company.id 
FROM employee
INNER JOIN company 
On employee.companyId= company.id
WHERE company.id IN (1,2,3)

1

对于你所查询的仅为公司ID为1的记录,这是正确的。

你需要编写类似以下的查询语句。

SELECT Id, Name FROM Employee WHERE CompanyId in (SELECT Id FROM Company)

现在我已经尝试了上述方法,它可以完成你所需要的查询。但是,如果要根据公司/母公司来获取期望的结果,请尝试以下查询。

SELECT e.Id, e.Names FROM Employee e WHERE e.CompanyId = 1 
    or e.CompanyId in (SELECT c.Id FROM Company c where c.ParentCompanyId = 1)

希望这能有所帮助。

这是我最初尝试的方法...但不确定这是否是正确的性能优化方式。 - Billa
为了性能,恐怕您必须进行检查。如果我能找到更好的方法,我也会研究一下。当然这取决于数据量的大小。如果您不处理数万条记录,那么我认为您应该没问题。不过我还会再次检查。谢谢。 - LiaqatG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接