0

次のようなテーブルがあります。

 a | b
---+---
 1 | a
 2 | a
 3 | a

 1 | b
 3 | b

 2 | c
 3 | c

これは、多対多の関係 a<->b を表します。次のように、既存のすべてのリレーション a<->count(b)<->a を取得したいと思います。

 a1 | a2 | count
----+----+-------
 1  |  2 |     1         #1<->a<->2
 1  |  3 |     2         #1<->(a,b)<->3

 2  |  1 |     1         #duplicate for 1<->a<->2
 2  |  3 |     2         #2<->(a,c)<->3

 3  |  1 |     2         #duplicate for 1<->(a,b)<->3 
 3  |  1 |     2         #duplicate for 2<->(a,c)<->3

単一の a についてはまだ管理していますが、すべてを循環させる方法がわかりません。

SELECT
 '1' AS a1,
 t1.a AS a2,COUNT(t1.b)
FROM 
 a_b t1
INNER JOIN(
  SELECT
   b
  FROM a_b
  WHERE
   a = '1'
  ) t2
ON
 t1.b = t2.b
WHERE t1.a != '1'
GROUP BY t1.a
ORDER BY t1.a;

 a1 | a2 | count
----+----+-------
 1  |  2 |     1
 1  |  3 |     2

a_b をそれ自体にクロス結合したり、外部スクリプトをループしたりせずに達成できますか?

これがSQLFiddle http://www.sqlfiddle.com/#!1/8b53a/1/0です

ティア

4

2 に答える 2

2

これは、集計を使用した基本的な「結合」クエリだと思います。

select ab1.a, ab2.a, count(*)
from a_b ab1 join
     a_b ab2
     on ab1.b = ab2.b and ab1.a <> ab2.a
group by ab1.a, ab2.a
于 2013-09-07T11:59:08.037 に答える
0

ゴードン・リノフの解決策に少し追加: 関係が二重にならないように (つまり、1-3 と 3-1)、where 句を追加しました。

select ab1.a as a1, ab2.a as a2, count(*)
from a_b ab1 join
     a_b ab2
     on ab1.b = ab2.b and ab1.a <> ab2.a
     where ab1.a < ab2.a
group by ab1.a, ab2.a
于 2013-09-07T12:06:58.680 に答える