【问题标题】:Recursive query to select Parent and Child cases in sql在sql中选择父子案例的递归查询
【发布时间】:2018-10-04 11:13:01
【问题描述】:

我正在尝试使用公用表表达式对查询进行递归。但是我对它不是很熟悉。该场景围绕在父案例和子案例之间,其中家长在登录时可以看到他自己的案例以及他所有的孩子案例等等。但是我无法使用 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

在关系表中

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 登录时,我应该看到最后两个案例。

【问题讨论】:

  • 请提供样本数据和期望的结果。
  • 请查看已编辑的问题@GordonLinoff

标签: sql common-table-expression


【解决方案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

【讨论】:

  • 谢谢@Tomasz。我现在如何在 cte 中使用案例表?
  • 在最后一次选择中,您可以加入案例表:SELECT * FROM cte1 INNER JOIN dbo.[Case] c on c.AssignedTo = [User]
【解决方案2】:

这是一个非常简单的分层 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;

参照。 https://gist.github.com/pedroreys/8336d6f4dcb63ba619c0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-08
    • 2016-05-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多