プロが教える店舗&オフィスのセキュリティ対策術

下記のようなテーブルがあり、
マスタの方は「*」が入っていれば、デフォルト行のような扱いをしたいのです。
・テーブルの1のデータはマスタのAと完全マッチしているので、Aの行の値が欲しい。
・テーブルの2のデータはマスタと完全一致はしないが、列4が「*」なのでBの行の値が欲しい。
・テーブルの3のデータはマスタと完全一致はしないが、列3と列4が「*」なので、Cの行の値が欲しい。


現在は、マスタを別名で完全一致用(m1)、列4が「*」用(m2)、列3と列4が「*」用(m3)の3つをFrom句に記述し、
Select句にて、m1がNULLなら、m2から取得、m2もNULLならm3から取得するというやり方をとっていますが、
実際の「*」がある組み合わせがたくさんあり、それだけインラインビューを用意すると遅くなっているので、
なんとかインラインビュー1つでなんとかならないものでしょうか?

テーブル
┌─┬──┬──┬─┐
│01│AAAA│X001│YY│←1
├─┼──┼──┼─┤
│01│AAAA│X001│ZZ│←2
├─┼──┼──┼─┤
│01│AAAA│X002│YY│←3
└─┴──┴──┴─┘

マスタ
┌─┬──┬──┬─┐
│01│AAAA│X001│YY│←A
├─┼──┼──┼─┤
│01│AAAA│X001│* │←B
├─┼──┼──┼─┤
│01│AAAA│* │* │←C
└─┴──┴──┴─┘

A 回答 (3件)

一致する項目の数で、レコードを選択すれば良いと思うので、



select T1,T2,T3,T4,M1,M2,M3,M4
from
(
select T.*,Mx.*,row_number() over(partition by T1,T2,T3,T4 order by CNT) R
from テーブル T,
(
select M1,M2,M3,M4,
decode(M1,'*',1,0)+decode(M2,'*',1,0)+decode(M3,'*',1,0)+decode(M4,'*',1,0) as CNT
from マスタ M
) Mx
where
decode(M1,T1,1,'*',1,0)=1 and
decode(M2,T2,1,'*',1,0)=1 and
decode(M3,T3,1,'*',1,0)=1 and
decode(M4,T4,1,'*',1,0)=1
)
where R=1

とか。
    • good
    • 0
この回答へのお礼

まさにやりたいことができました!
実際に組み込みたいSQLは巨大で複雑なものですが、
試してみたいと思います。

ありがとうございました。

お礼日時:2009/12/11 16:48

すでに#1のSQLに準ずるものになっているのであれば、キーにインデックスが無いとかはありませんか?



蛇足
インラインビューとは普通以下のようなものを指すを思います。今回のSQLは単に同一テーブルの複数回結合です。マスタにユニークインデックスが適切に作成されていれば、通常マスタが原因で遅くなるとは思えないのですが・・・

select a.*, b.* from (
select * from table1 where key = 1
) a, table2 b
where a.key = b.key
    • good
    • 0
この回答へのお礼

コメントありがとうございます。

実際、該当するSQLをオブジェクトブラウザ等で実行すると、
100件ほどなのに、15秒ほどかかり、
マスタを複数回結合しているのをやめると、4秒になりました。
マスタにはユニークが設定されていますが、
複数回結合の相手が大きなViewのため、それで遅いのかも知れません。

お礼日時:2009/12/11 16:47

この手の質問は試行したSQLを書かないと、アドバイスが付きにくいと思います。


ざっと考えてこんなSQLでイケるのでわないかと・・・データ部の情報がないので、そのあたりはテキトーです。

select case when マスタ1.データ is not null then マスタ1.データ
when マスタ2.データ is not null then マスタ2.データ
else マスタ3.データ end as "データ"
from テーブル, マスタ マスタ1, マスタ マスタ2, マスタ マスタ3
where マスタ1.列1(+) = テーブル.列1 and マスタ1.列2(+) = テーブル.列2
and マスタ1.列3(+) = テーブル.列3 and マスタ1.列4(+) = テーブル.列4
and マスタ2.列1(+) = テーブル.列1 and マスタ2.列2(+) = テーブル.列2
and マスタ2.列3(+) = テーブル.列3 and マスタ2.列4(+) = '*'
and マスタ3.列1(+) = テーブル.列1 and マスタ3.列2(+) = テーブル.列2
and マスタ3.列3(+) = '*' and マスタ3.列4(+) = '*'
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

>現在は、マスタを別名で完全一致用(m1)、列4が「*」用(m2)、列3と列4が「*」用(m3)の3つをFrom句に記述し、
>Select句にて、m1がNULLなら、m2から取得、m2もNULLならm3から取得するというやり方をとっていますが、
>実際の「*」がある組み合わせがたくさんあり、それだけインラインビューを用意すると遅くなっているので、
>なんとかインラインビュー1つでなんとかならないものでしょうか?

上記で伝えた気になっていました。
わかりにくくて申し訳ありません。
現状はまさしく回答して頂いた通りなのですが、
マスタを別名で何個も宣言しているので、
これが1個にならないか?という質問でした。

お礼日時:2009/12/10 17:52

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す