2

特定の人のフィールドが交差するフィールドを返そうとしています。これが意味することは

Name    Friend
----    -----
Joe     Sally
Joe     Bill
Mary    Sally
Mary    Michael
Mike    Joe
Bill    Bill
Bill    Sally
Gil     Sally
Gil     Bill
Gil     David

たとえば、Joe の 2 番目の列に一致する人物のリストが必要な場合、Sally と Bill の両方に一致する必要があります。Mary には Bill がありませんが、Bill だけがこの条件に一致します。ギルにはサリーとビルがいますが、デビッドもいます。したがって、Bill のみを返す必要があります。それは共通のフィールドを返すので何かがうまくいくと思っていましINTERSECTたが、それは誰かがそれ以上持っていることを説明していないと思います。やりたいことを実行するための SQL クエリの書き方がわかりません。

はっきり言って、Joe とまったく同じ友人を持つ名前のリストです。

4

1 に答える 1

0

重複なし

SELECT p2.name
FROM   people AS p1
JOIN   people AS p2 ON p2.number = p1.number
                   AND p2.name <> p1.name    -- exclude self-join
WHERE  p1.name = 'Joe'
AND NOT EXISTS (
   SELECT 1 
   FROM   people p3
   WHERE  p3.name = p2.name  
   AND    p3.number <> p1.number
   )
GROUP  BY p2.name
HAVING count(*) = (SELECT count(*) FROM people WHERE name = 'Joe')

最後の条件は、 Joe以外AND NOT EXISTS ...の友人がいる人を除外したい場合にのみ必要です。あなたの例では、結果から 除外されます。
Gil

これは、関係分割(自己参照テーブルを使用する) の特殊なケースです。この関連する回答で、クエリ手法のすべての武器を見つけることができます:
How to filter SQL results in a has-many-through relationship

重複あり

重複がある可能性がある場合 (質問の最初のドラフトのように)、状況はもう少し複雑になります。

WITH p AS (
   SELECT name, number, count(*) AS ct
   FROM   people
   GROUP  BY name, number
   )
SELECT p2.name
FROM   p AS p1
JOIN   p AS p2 ON p2.number = p1.number
              AND p2.ct = p1.ct
              AND p2.name <> p1.name    -- exclude self-join
WHERE  p1.name = 'Joe'
AND NOT EXISTS (
   SELECT 1 
   FROM   p p3
   WHERE  p3.name = p2.name  
   AND    p3.number <> p1.number
   )
GROUP  BY p2.name
HAVING count(*) = (SELECT count(*) FROM p WHERE name = 'Joe')
于 2013-03-09T02:45:12.980 に答える