1

兄弟グループを特定するためにいくつかのレコードをリンクしようとしています。これを行う方法は、同じ親を持つクライアントを特定することです。

SQL のサンプルは次のとおりです。

SELECT
A.ClientID,
B.ParentID

FROM A
LEFT JOIN B ON B.ClientID to A.ClientID
AND B.REL_END is NULL AND B.REL_CODE = 'PAR'

次の形式でデータを返します。

     Client ID     Parent ID
     1             A
     1             B
     2             C
     2             D
     3             C
     3             E
     4             C
     4             D

次のように表示したい方法:

     Client ID    No. of Siblings
     1            0
     2            2
     3            2
     4            2         

うまくいけば、この表は、子供 1 には兄弟が 0 人 (2、3、4 と親を共有していない)、子供 2 には兄弟が 2 人 (3 と 4)、子供 3 には兄弟が 2 人 (2 と 4)、子供 4 には兄弟が 2 人いることを示しています ( 2,3)。これを達成するのは簡単なように思えますが、その方法を考えるのに本当に苦労しています! 兄弟と見なされるために、子供が別の子供と 1 つの親のみを共有する場合があるため、少し混乱が生じていると思います。

うまくいけば、これは明らかです、ありがとう。

編集: 明確にするために、関係は、親 ID を別の子と共有する子によって識別されます (ID は一意ですが、この例では一般的なものを提供しました)。したがって、Child 2、3、および 4 はすべて、ID が C の親を持っているため、兄弟と見なされます。

4

3 に答える 3

2

このクエリを試すと、目的の出力が表示されます。

with c_data as (
    select a.clientid, b.parentid, count(a.clientid) over (partition by parentid order by     parentid) as c_parents
    FROM A
      LEFT JOIN B ON (B.ClientID = A.ClientID)
        AND B.REL_END is NULL AND B.REL_CODE = 'PAR'
)
select clientid as "Client ID", max(c_parents) -1 as "No of Siblings"
from c_data
group by clientid;

例:

SQL> with c_data as (
  2  select a.clientid, b.parentid, count(a.clientid) over (partition by parentid order by parentid) as c_parents
  3  FROM A
  4  LEFT JOIN B ON (B.ClientID = A.ClientID)
  5  AND B.REL_END is NULL AND B.REL_CODE = 'PAR'
  6  )
  7  select clientid as "Client ID", max(c_parents) -1 as "No of Siblings"
  8  from c_data
  9  group by clientid;

 Client ID No of Siblings
---------- --------------
         1              0
         2              2
         4              2
         3              2

Transcurrido: 00:00:00.03
SQL>

分析関数を使用して、現在のタプルに関連する親 ID によって分割されたすべてのクライアント ID をカウントして、共通の親を持つすべてのクライアントをカウントします。

プロジェクションの後、各クライアントに共通の親の最大数を取得し、クライアント自体の 1 を引きます。

お役に立てれば!

よろしく!

于 2012-07-05T15:36:04.940 に答える
1

これはかなり複雑です。それぞれの子に対して正確に 2 人の親を想定できる場合は、次のようにすることができます。

select c.*, count(*) over (partition by min_parent, max_parent) - 1 as NumSiblings
from (SELECT A.ClientID, min(B.ParentID) as min_parent, max(b.parentid) as max_parent
      FROM A LEFT JOIN
           B
           ON B.ClientID to A.ClientID AND B.REL_END is NULL AND B.REL_CODE = 'PAR'
      group by a.clientid
     ) c

これが行うことは、各クライアントの 2 つの親を計算することです。次に、windows 関数を使用して、まったく同じ親を持つクライアントの数をカウントします。「-1」は、すべての子がカウントされ、現在の子をカウントしたくないためです。

2 つ以上の親を持つことができる場合、クエリはより複雑になります。

親を (2 つではなく) 1 つだけ共有したい場合は、自己結合を使用して処理できます。

with cp as (SELECT A.ClientID, B.ParentID
            FROM A LEFT JOIN
                 B
                 ON B.ClientID to A.ClientID AND B.REL_END is NULL AND B.REL_CODE = 'PAR'
           )
select cp.client_id, count(distinct cp1.client_id) as NumSiblings
from cp left outer join
     cp cp1
     on cp.parent_id = cp1.parent_id and cp.client_id <> cp1.client_id
group by cp.client_id
于 2012-07-05T15:27:56.633 に答える
0

テーブルとリレーションがどのように作成されているかわかりませんが、次のようなことができます。

SELECT ClientID, sum(NumberOfSibling) as NumberOfSibling
from(
    SELECT A.ClientID, (select count(ClientID) 
                        from A2
                        LEFT JOIN B2 ON B2.ClientID to A2.ClientID
                        AND B2.REL_END is NULL AND B2.REL_CODE = 'PAR'
                        where B2.ParentID = B.ParentID) as NumberOfSibling
    FROM A
    LEFT JOIN B ON B.ClientID to A.ClientID
    AND B.REL_END is NULL AND B.REL_CODE = 'PAR'
) GROUP BY ClientID

説明 : 私はあなたの要求を受け取り、同じ親を持つ兄弟の合計を返すように 2 番目の結果を変更しました (これthe select count(*) ...は、条件についてよくわからない部分でもあります)。そして、これを別の ClientID でグループ化して、2 つの親の合計を取得します。

于 2012-07-05T14:55:15.860 に答える