递归查询以选择SQL中的父子案例

时间:2018-10-04 11:13:02

标签: sql common-table-expression

我正在尝试使用Common Table Expression在查询上实现递归。但是我对它不是很熟悉。该方案围绕父子案例,其中父级登录后可以看到自己的子案例以及所有子案例,依此类推。但是我无法使用cte表达式来做到这一点。

我有一个用户表和一个包含主用户和次用户的关系表。主用户是父级,次用户是子级。

下面是我的查询。

select *
from dbo.[Case] c
left join dbo.[User] u on c.AssignedTo = u.UserId
left join dbo.[User] uu on c.AssignedTo = uu.UserId
where uu.UserId in (select SecondaryUser from  dbo.[Relations]
                    where PrimaryUser = 'f422233f-9c70-4052-81a5-e2525707df0b') 
    or u.UserId = 'f422233f-9c70-4052-81a5-e2525707df0b'

但是上面的查询仅返回一个父项和一个子项。而且我想使用公用表表达式来拥有多个父母及其多个孩子的情况。

假设某些用户如下

    Id   Name   Email 
    001  Salar  salar@gmail.com
    002  Ather  ather@gmail.com
    003  John   john@gmail.com

在RelationShip表中

Id   PrimaryUser SecondaryUser
101    001       002
001    002       003

及其分配的案件

Id     CaseTitle    CaseDescription  AssingedTo
101    Case 1       First case    001
102    Case 2       Second case   002
103    Case 3       Third case    003

因此,当我登录到001 id时,我应该看到所有三种情况,而当我登录002时,我应该看到最后两种情况。

2 个答案:

答案 0 :(得分:1)

此查询将返回与第一个ID相关的所有用户ID。您可以将结果与案例结合起来:

declare @Users as table
    (UserId  int)
;

declare @Relations as table
    (PrimaryUser  int, SecondaryUser int)
;    

INSERT INTO @Relations
    (PrimaryUser, SecondaryUser)
VALUES
    (1,2),
    (1,3),
    (2,4),
    (2,7),
    (2,8),
    (5,6),
    (6,19)

INSERT INTO @Users
    (UserId)
VALUES
    (1),
    (2),
    (3),
    (4),
    (5),
    (7),
    (5),
    (6),
    (19),
    (20)

;WITH cte1 AS (
  SELECT UserId AS [User]
  FROM @Users 
  WHERE UserId = 5
  GROUP BY UserId
UNION ALL  
  SELECT SecondaryUser  AS [User]
  FROM cte1
  JOIN @Relations t 
    ON t.PrimaryUser = cte1.[User]   
)
SELECT [User] FROM cte1

答案 1 :(得分:0)

这是一个非常简单的分层CTE示例:

with t(level,path,boss,name) as 
(
        -- this is the starting point (can be one or more records)
        select 0,name,boss,name from @empl where boss is null

        union all

        -- here you construct the tree (via the join conditions)
        select
            level + 1,
            path + ' > ' + e.name,
            e.boss, e.name 
        from @empl e
            inner join t on e.boss = t.name                
) 
-- here you collect the results from the cte
select * 
from t 
order by path;

Cf。 https://gist.github.com/pedroreys/8336d6f4dcb63ba619c0