sql - 在自连接字段上执行递归 SQL 查询的最佳方法是什么(以及通过 nhibernate 执行此操作?)

标签 sql sql-server nhibernate recursive-query

我有一个名为Employee的数据库表,它包含以下列:

  • 身份证
  • 姓名
  • 经理 ID

名为 ManagerId 的列是同一个表中的自联接字段(因为经理只是另一个员工。

我现在想要运行一个查询:

接受 Id 参数(采用单个经理)并希望获取该人员中的所有人员。所以如果我这样做

 Select * from ManagerId = 1

我只会获得该经理的直接报告,并且我希望递归地获得该经理的所有人员。

  • 直接下属
  • 直接下属的直接下属
  • 直接下属的直接下属
  • 等等。 。 .

另外,我在我的解决方案中使用了 Fluent nhibernate,所以也想在那里得到一些建议。如果我在代码中循环执行此操作,如果经理下面有很多层人员,那么它似乎会运行许多查询。

最佳答案

使用递归 CTE,您可以构建层次结构。按搜索条件过滤顶级查询,您可以获得所需的结果。

DECLARE @id INT;
SET @id = 3;

WITH    Emp
          AS (SELECT    te.id
                      , te.Name
                      , te.ManagerId
                      , CAST(NULL AS VARCHAR(10)) AS ManagerName
              FROM      dbo.tblEmployee AS te
              -- Get entire heirarchy with the NULL ManagerId
              --WHERE     ManagerId IS NULL
              WHERE     te.id = @id
              UNION ALL
              SELECT    te2.id
                      , te2.Name
                      , e.id
                      , e.Name
              FROM      dbo.tblEmployee AS te2
              JOIN      Emp e
                        ON e.id = te2.ManagerId
             )
    SELECT  *
    FROM    Emp;

更新: 对于您关于不包含传递的 id 记录的评论,您可以执行以下操作:

最简单的方法是在最后一个选择中添加一个 where 子句:

SELECT  *
FROM    Emp
WHERE emp.ID <> @id;

或者,如果您不需要为层次结构的顶层填充 ManagerName 字段,则可以使用 CTE 中的第一个 where 子句:

SELECT    te.id
, te.Name
, te.ManagerId
, CAST(NULL AS VARCHAR(10)) AS ManagerName
FROM      dbo.tblEmployee AS te
-- Get entire heirarchy with the NULL ManagerId
--WHERE     ManagerId IS NULL
--WHERE     te.id = @id
WHERE ManagerId = @id

关于sql - 在自连接字段上执行递归 SQL 查询的最佳方法是什么(以及通过 nhibernate 执行此操作?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23420153/

相关文章:

Java SQL Server 2012 无法打开数据库错误

c# - 将 SqlCommand 转换为 T-SQL 命令

sql-server - 如何在不重新启动实例的情况下使用 SQL Server 中的查询清除错误日志?

c# - 如何最小化锁定同时保持数据库相关操作是原子的

sql - 如何 "HAVING COUNT(DISTINCT(col1, col2))"

c# - 在 SQL 列中查找字符串

c# - Fluent NHibernate 自动映射错误

.net - NHibernate ISession Flush : Where and when to use it, 以及为什么?

sql - 对SQL函数中的 "NEW"关键字感到困惑

c# - 我应该将实体(持久)对象转换为 DTO 对象吗?