トップページに戻る    次のSQLパズルへ    前のSQLパズルへ

4-15 加算の単位元をふまえたouter unionもどき

SQLパズル

ZaikoTable
High  Zaiko
----  -----
3.00      5
3.00     10
3.50      2
3.50      5
4.00      2

HanbaiTable
High  hanbai
----  ------
3.00       2
3.00       2
3.50       1
3.50       3
4.00       2
4.20       9

Highごとの、在庫数と販売数の合計を出力する。

出力結果
High  Zaiko  hanbai
----  -----  ------
3.00     15       4
3.50      7       4
4.00      2       2
4.20      0       9

こちらを参考にさせていただきました


データ作成スクリプト

create table ZaikoTable(High,Zaiko) as
select 3.00, 5 from dual union all
select 3.00,10 from dual union all
select 3.50, 2 from dual union all
select 3.50, 5 from dual union all
select 4.00, 2 from dual;

create table HanbaiTable(High,hanbai) as
select 3.00,2 from dual union all
select 3.00,2 from dual union all
select 3.50,1 from dual union all
select 3.50,3 from dual union all
select 4.00,2 from dual union all
select 4.20,9 from dual;


SQL

■■■完全外部結合を使う方法■■■
select nvl(a.High,b.High) as High,
nvl(a.Zaiko,0) as Zaiko,
nvl(b.hanbai,0) as hanbai
from (select High,sum(Zaiko)  as Zaiko  from ZaikoTable group by High) a
      full join
     (select High,sum(hanbai) as hanbai from HanbaiTable group by High) b
     on (a.High = b.High)
order by High;

■■■outer unionもどきを使う方法■■■
select High,sum(Zaiko) as Zaiko,sum(hanbai) as hanbai
from (select High,Zaiko,0 as hanbai from ZaikoTable union all
      select High,0 as Zaiko,hanbai from HanbaiTable)
group by High
order by High;


解説

完全外部結合を使ってもいいですが、
0が加算の単位元であることふまえたouter unionもどきを使ってます。

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
ちなみに、下記だとダメです。
select nvl(a.High,b.High) as High,
sum(nvl(a.Zaiko,0)) as Zaiko,
sum(nvl(b.hanbai,0)) as hanbai
  from ZaikoTable a full join HanbaiTable b
    on a.High = b.High
group by nvl(a.High,b.High)
order by High;

High  Zaiko  hanbai
----  -----  ------
   3     30       8
 3.5     14       8
   4      2       2
 4.2      0       9

なぜ、ダメかというと、リレーションが多対多なので、
多対多の結合が発生するからです。

9-63 導出テーブルを減らせ