0

私は、SQL クエリを使用して少し作業不能な状況に陥っていることに気づきました。何かが足りないか、何か新しいことを学べることを願っています。私が扱っているDB2データベースの構造は、この種のクエリ用に正確に構築されているわけではありませんが、私はこれを任されています...

Table People と Table Groups があるとします。グループには複数のユーザーを含めることができ、1 人のユーザーが複数のグループに所属することができます。うん、もうぐちゃぐちゃ。いずれにせよ、2 つをリンクするいくつかの中間テーブルがあります。問題は、グループのリストから始めて、それらのグループ内のすべての人を取得し、次にその人が所属しているすべてのグループ (最初のグループ セットのスーパーセット) を取得する必要があることです。これは、グループから始めて人々に参加し、戻って再びグループに参加することを意味します。結果セット内の両方のテーブルからの情報も必要なので、多くの手法が除外されます。

追加情報を得るために、これを他の多くのテーブルと結合する必要があり、クエリは膨大で扱いにくく、遅くなります。People から始めて、それを Groups に参加させてから、指定された一連のグループ (サブクエリを介して行われる) に 1 つのグループがある場合、すべてのグループを指定する方法があるかどうか疑問に思っています。その人は返さなければならないからです。これを実現する方法はわかりませんが、SQL でこれを実現する比較的クリーンな方法があると考えています (期待しています)。

簡単で汚い例:

SELECT ...
FROM GROUPS g
  JOIN LINKING_A a 
     ON g.GROUPID = a.GROUPID
        AND GROUPID IN (subquery)
  JOIN LINKING_B b 
     ON a.GROUPLIST = b.GROUPLIST
  JOIN PEOPLE p 
     ON b.PERSONID = p.PERSONID
    --This gets me all people affiliated with groups, 
    -- but now I need all groups affiliated with those people...
  JOIN LINKING_B b2 
     ON p.PERSONID = b2.PERSONID
  JOIN LINKING_A a2 
     ON b2.GROUPLIST = a.GROUPLIST
  JOIN GROUPS g2
     ON a2.GROUPID = g.GROUPID

そして、結果セットで p と g2 から情報を返すことができます。困っているところがわかります。このクエリで実行される他の多くの結合は言うまでもなく、いくつかの大きなテーブルで多くの結合が行われます。PEOPLE を GROUPS に結合してクエリを実行できるようにする必要があります。次に、サブクエリに関連付けられたグループがある人がいる場合、PEOPLE のそのエントリに関連するすべてのグループを返す必要があることを指定します。私は GROUP BY がちょうどいいかもしれないと思っていますが、実際に知るのに十分なほど使用していません。したがって、ビルがグループ A、B、および C の一部であり、サブクエリがグループ A を含むセットを返す場合、結果セットにはグループ A、B、および C とともにビルが含まれるはずです。

4

3 に答える 3

0

以下は、指定されたグループ リストに含まれるすべてのグループを取得する簡単な方法です。これは役に立ちますか?

Select g.*
From Linking_B b
   Join Linking_B b2
      On b2.PersonId = b.PersonId
   Join Group g
      On g.GroupId = b2.GroupId
Where b.Groupid in (SubQuery)
于 2013-06-12T23:29:55.710 に答える
0

最初にレコードを取得したい人のリストを作成し、それを使用してそれらの人々のすべてのグループを照会すると思います。これは、適切な結合が追加された任意の数のリンク テーブルで機能します。

with persons_wanted as
(
     --figure out which people are in a group you want to include
     select p.person_key
     from person p
     join link l1
     on p.person_key = l1.person_key
     join groups g
     on l1.group_key = g.group_key
     where g.group name in ('GROUP_I_WANT_PEOPLE_FROM', 'THIS_ONE_TOO')
     group by p.person_key --we only want each person_key once
)
--now pull all the groups for the list of people in at least one group we want
select p.name as person_name, g.name as group_name, ...
from person p
join link l1
on p.person_key = l1.person_key
join groups g
on l1.group_key = g.group_key
where p.person_key in (select person_key from persons_wanted);
于 2013-06-14T18:38:03.270 に答える
0

Linking_A と Linking_B の両方がある理由がわかりません。通常、2 つのマスター テーブル間の多対多の関係を表すために必要なのは、GroupID と PersonId を持つ単一の関連付けテーブルだけです。

問題をより理解しやすいチャンクに分割するのに役立つように、「共通テーブル式」[CTE] を使用することをよくお勧めします。CTE は、メインの SELECT クエリを開始する前に複数の CTE を含めることができる WITH 句を使用して指定されます。

開始したいグループのリストがサブクエリで指定されていると仮定するので、それが最初の CTE になります。次は、それらのグループに属する人を選択します。クエリの最後の部分では、ユーザーが属するグループを選択し、両方のマスター テーブルから列を返します。

WITH g1 as
(subquery)
, p1 as
(SELECT p.*
   from g1
   join Linking a1  on g1.groupID=a1.groupID
   join People  p   on p.personID=a1.personID )
SELECT p1.*, g2.*
  from p1
  join Linking a2   on p2.personID=a2.personID
  join Groups  g2   on  g2.groupID=a2.groupID
于 2013-06-13T00:52:23.277 に答える