[pgsql-jp: 26098] Re: 3つ以上のテーブルを無条件に結合する方法

ichikawa @ is.ocha.ac.jp ichikawa @ is.ocha.ac.jp
2002年 5月 23日 (木) 22:18:55 JST


市川です.

At Thu, 23 May 2002 20:00:19 +0900,
K.Ohyama <ohyama @ ktsnet.co.jp> wrote:
> 
>  大山です。
>  SQLについてですが、
> 3つ以上のテーブルを無条件に結合する方法ってあるのでしょうか?
>  UNIONでも、JOIN、OUTER JOINでも実現出来そうになく、
> そもそもこんな問い合わせが実現出来るのか怪しくなってメールしました。
> 
>  例えば、3つのテーブルt1、t2、t3が下記の様になっているとして、
> 
> => SELECT * FROM t1;
>  i | j
> ---+---
>  0 | a
>  1 | b
> 
> => SELECT * FROM t2;
>  i | j
> ---+---
>  0 | c
>  2 | b
>  4 | a
> 
> => SELECT * FROM t3;
>  i | j
> ---+---
>  3 | c
>  5 | d
> 
>  次の結果を問い合わせることが可能か?ということです。
> 
> => SELECT ??????????????;
>  i | j | i | j | i | j
> ---+---+---+---+---+---
>  0 | a | 0 | c | 3 | c
>  1 | b | 2 | b | 5 | d
>    |   | 4 | a |   |
> 
>  要するに3回SQLを実行した結果をそのまま横に結合した
> 形です。

各タプルが何番目かを表す属性が入っておりませんので.単一の SQL 文では
無理だろうと思います.若干手続き的ですが,PL/pgSQL であれば,
(効率は度外視するとして) 次のような感じで行けるのでは?

# PL/pgSQL の勉強がてら作成しているのでベストな手続きかどうかはちょっと
# 不安ですが ...


1. 作業用の表を作成しておく

create table t_1 (n int4, i int4, j int4);
create table t_2 (n int4, i int4, j int4);
create table t_3 (n int4, i int4, j int4);
create table res (i1 int4, j1 text,
	i2 int4, j2 text, i3 int4, j3 text);

2. 手続きを登録

create function t123() returns int4 as'
declare
  x1 t1%ROWTYPE;
  x2 t2%ROWTYPE;
  x3 t3%ROWTYPE;
  mx int4;
  n int4;
  i int4;
  

begin
  delete from res;
  delete from t_1;
  delete from t_2;
  delete from t_3;

  select into mx count(*) from t1;
  select into n count(*) from t2;
  if n > mx then
     mx := n;
  end if;
  select into n count(*) from t3;
  if n > mx then
     mx := n;
  end if;
  -- raise debug ''mx = %'', mx;

  n := 1;
  for x1 in select * from t1 order by i loop
     insert into t_1 values (n, x1.i, x1.j);
     n := n+1;
  end loop;
  for i in n .. mx loop
     insert into t_1 values (i, null, null);
  end loop;

  n := 1;
  for x2 in select * from t2 order by i loop
     insert into t_2 values (n, x2.i, x2.j);
     n := n+1;
  end loop;

  n := 1;
  for x3 in select * from t3 order by i loop
     insert into t_3 values (n, x3.i, x3.j);
     n := n+1;
  end loop;

  insert into res
     select t_1.i, t_1.j, t_2.i, t_2.j, t_3.i, t_3.j
     from t_1 left outer join t_2 on t_1.n = t_2.n
              left outer join t_3 on t_1.n = t_3.n;
  return 0;
end;
' language 'plpgsql';
  



pgsql-jp メーリングリストの案内