0

personid 列と licensetypeid 列を持つテーブル P があります。

各個人は複数のライセンス タイプを持つことができ、その個人 ID のテーブルに行を追加できます。

personid が 1 と 5 の両方の licenseid を持つ行を見つける必要があります。

私は書くことができません:

SELECT personid, licensetypeid 
FROM P 
WHERE licensetypeid=1 AND licensetypeid=5;

これを行うには、自己結合を使用する必要があると聞きました。この問題を解決するために自己結合を行うにはどうすればよいですか?

4

5 に答える 5

4

テーブルに複数回アクセスする自己結合やその他の手法は機能しますが、パフォーマンスが低下する可能性があり、より大きな ID セットに一般化する必要がある場合は扱いにくくなります。

1 人あたりの一致する行の数を数えることで、テーブルへの 1 回の参照でそれを行うことができます。

select personid from P
  where licensetypeid in ('1','5')
  group by personid
  having count(*) = 2

より大きな licensetypeid 値が必要な場合は、これを簡単に拡張できます。

select personid from P
  where licensetypeid in ('1','5','7')
  group by personid
  having count(*) = 3

(自己結合バージョンでは、追加の値ごとに追加の結合を追加する必要があります)

または、より大きなタイプのセットから少なくとも 2 つのタイプを持つ人を見つけたい場合は、次のようにします。

select personid from P
  where licensetypeid in ('1','5', '7', '10')
  group by personid
  having count(*) >= 2

サンプル クエリとは異なり、licensetypeid は結果セットに含まれていません。何らかの理由でそれが必要な場合は、2 つの値の場合に簡単なトリックを実行できます。

select personid, min(licensetypeid) licensetype1, max(licensetypeid) licensetype2
  from P
  where licensetypeid in ('1','5')
  group by personid
  having count(*) = 2

しかし、より一般的なアプローチは、値を単純なコレクションにグループ化することです。

select personid, collect(licensetypeid) licensetypeidlist
  from P
  where licensetypeid in ('1','5')
  group by personid
  having count(*) = 2
于 2011-04-07T14:53:57.693 に答える
2
select personid, licensetypeid
from P P1
where exists (
   select 1
   from P P2
   where P2.personid = P1.personid
      and P2.licensetypeid = 1
) and exists (
   select 1
   from P P2
   where P2.personid = P1.personid
      and P2.licensetypeid = 5
)
于 2011-04-07T11:53:21.080 に答える
1
SELECT distinct
       p1.personid
      ,p1.licensetypeid 
      ,p2.licensetypeid
from P p1, P p2
WHERE p1.personid = p2.personid
AND   p1.licensetypeid = 1
AND   p2.licensetypeid = 5
;
于 2011-04-07T12:02:36.240 に答える
0

必要なライセンスタイプのセットが「固定」されている場合、または少なくとも必要なライセンスタイプのセットのカーディナリティが固定されている場合、指定された回答は正常に機能します。

それ以外の場合は、「リレーショナル除算」と呼ばれるものに相当するSQLを作成する必要があります。

それは次のようになります:

(1)必要なライセンスタイプの少なくとも1つを欠いている人のセットを計算します。

SELECT personid 
from P 
WHERE EXISTS
  (
    SELECT licenseid 
    from NEEDEDLICENSETYPE AS NLT 
    WHERE NOT EXISTS (
      SELECT * 
      FROM P AS PBIS 
      WHERE 
        PBIS.personid = P.personid AND
        PBIS.licensetype = NLT.licensetype
    )
  )

NEEDELICENSETYPEは、特定の呼び出しで必要なライセンスタイプのセットを計算するために必要なSQLステートメントを表します。

(2)(1)に表示されていない番号の人のデータを選択します。

SELECT ... FROM P WHERE personid NOT IN (...)
于 2011-04-07T12:27:19.910 に答える
0

これを試して

select personid,licensetypeid from P where licensetypeid in ('1','5')
于 2011-04-07T11:30:58.377 に答える