私は、親子関係の可能性のある以下のような単純なテーブルを持っています。これは実際には非常に大きなテーブルですが、これは公正な表現です。 「孫」の関係はありません。シンプルだが非効率な親子関係クエリを改善する方法
私はこれをある入力値でフィルタリングされた少し異なるテーブルに変換する必要があります。
declare @pc table (myId char(1) not null, parentId char(1) );
insert into @pc (myId, parentId) values ('A', null)
insert into @pc (myId, parentId) values ('B', 'A')
insert into @pc (myId, parentId) values ('C', 'A')
insert into @pc (myId, parentId) values ('D', null)
insert into @pc (myId, parentId) values ('E', null)
insert into @pc (myId, parentId) values ('F', 'E')
insert into @pc (myId, parentId) values ('G', null)
insert into @pc (myId, parentId) values ('H', 'G')
insert into @pc (myId, parentId) values ('I', 'G')
insert into @pc (myId, parentId) values ('J', 'G')
insert into @pc (myId, parentId) values ('K', null)
-- This is the results I need
declare @target table (myId char(1) not null, parentId char(1), hasFamily bit);
"A" の
与えられた入力は、その後、私はこのような3行必要があります:A.私は "家族・グループ" に属しているすべてのものを必要とする、つまり
A NULL 1
B A 1
C A 1
を
「D」を考えるA NULL 1
B A 1
C A 1
私はちょうど必要があります:「B」私は同じ出力、(Aさんであることを起こる)Bの家族グループ内のすべてを必要と考えます誰がD'sの家族の中ではありませんので、1行が:
D NULL 0
null
を考えると、私はセットテーブル全体のデータを必要とするが、適切な行を「持つ家族」かではないとしてマーク。ここで
は、技術的に正しいです私の試みだが、それはそれを行うには、データの3回のパスを取るすべてでは効率的ではありません。
declare @testcase char(1) = 'B';
-- The inefficient method
INSERT INTO @target(myId,parentId)
SELECT pc.myId, pc.parentId
FROM @pc pc
WHERE(pc.myId = ISNULL(@testcase, pc.myId))
OR (pc.parentId [email protected]);
INSERT INTO @target(myId,parentId)
SELECT pc.myId, pc.parentId
FROM @pc pc
WHERE pc.myId IN (SELECT parentId FROM @target)
AND pc.myId NOT IN (SELECT myId FROM @target);
update t
set t.hasFamily = 1
from @target t
left outer join @target t2
on t.myId = t2.parentId
where t.parentId is not null or t2.myId is not null;
あなたはこの問題を見ているのより良い方法を見ることができますか?
はい、これはすべての行にhasFamilyフラグを設定する役立ちますが、それはまた別のネストされた2つのサブクエリを取りますか、および/または(不正なクエリプランの原因と思われる)一連のグループを検索します。 –
これは推測か、実際の勉強計画はありますか?データのパスは1回だけで、入れ子のレベルは1つのみです。ウィンドウ関数は非常に効率的です。 –
"と" nor "または"私の提案されたクエリで使用されています。だから私はなぜあなたがそこにあると言っているのか理解できない。 –