2

SQLを使用しています。ユーザーの子孫のIDのリストを取得しようとしています。だから、私は持っていると言う:SQL再帰CTEが予想よりも多くの結果を返します

Id | ManagerId | Name 
---|-----------|------ 
4 | NULL  | James Smith 
7 | 4   | John Doe (1) 
8 | 7   | John Doe (2) 
9 | 8   | John Doe (3) 
10 | 8   | John Doe (4) 

そして、私は戻って4, 7, 8, 9, 10を取得したいです。

WITH UsersCTE AS (
    SELECT Id, 
      ManagerId 
    FROM Users 
    WHERE IsActive = 1 
    UNION ALL 
    SELECT A.Id, 
      UsersCTE.Id 
    FROM UsersCTE 
      INNER JOIN Users AS A 
       ON A.ManagerId = UsersCTE.ManagerId 
) 

SELECT * 
FROM UsersCTE; 

どの作品の種類:オンライン周りに推奨されるアプローチを見ると、私のようにやった再帰CTEを作成することです。それは、私が欲しいidsを取得することから始まり、その後、ちょうど消えて、すべての種類の礼儀でidsを取得し始めます。どのように動作するのかわからないと告白しますが、私が望む結果を与えるものではありません。その代わりに、この私に与えている:

enter image description here

は、どのように私はそれは私が欲しいだけのIDを与えることを得ることができます。参考までに、私はこのリストを取得して、dbを問い合わせて、現在のユーザーと管理している子孫の注文リストを取得する必要があります。私はデータアクセスのためにEF6を使用しており、このCTEをビューにして適切にクエリを作成する予定ですが、より良い推奨事項が公開されています。

答えて

2

リライトとしては、以下:

WITH UsersCTE AS (
    SELECT Id, 
      ManagerId 
    FROM Users 
    WHERE IsActive = 1 and ManagerID is null 
    UNION ALL 
    SELECT A.Id, 
      UsersCTE.Id 
    FROM UsersCTE 
      INNER JOIN Users AS A 
       ON A.ManagerId = UsersCTE.Id and A.IsActive = 1 
) 

SELECT * 
FROM UsersCTE; 

最初の部分におけるヌルフィルタは、あなたのCTE、すなわちそれにないマネージャと従業員の基本ケースを与えるアンカー。もう1つの変更は、2番目のパートの結合条件にあります。更新された条件は、マネージャIDと従業員IDを一致させます。

Demo

+0

ああ、わかりました。今は理にかなっている。お手伝いありがとう! – Gup3rSuR4c

+1

再帰メンバで 'WHERE IsActive = 1'を繰り返す必要があるでしょう。 –

+0

ああ、もちろん。早くそれをオーバーレイクしました! –

関連する問題