
助けてください……(T-T)
oracleをつかっていますが、SQLが苦手すぎて、どうしたらいいか分かりません。。。
解決策をご存じの方、教えていただけないで しょうか?
テーブルは下記の2つがあります。
(1)Aテーブルの1カラムに、複数の商品IDを格 納している(カンマ区切り) (2)Bテーブルには、商品ID&商品名の一覧が ある
このAテーブルの商品ID列に番号から、Bテー ブルの商品名を取得したいです。
■Aテーブル
no | 商品ID
1001 | 1、2
1002 | 1、2、3
1003 | 3
■Bテーブル
商品ID | 商品名
1 | 商品A
2 | 商品B
3 | 商品C
■とりたいデータの形
1001 | 商品A、商品B
1002 | 商品A、商品B、商品C
1003 | 商品C
カンマ区切りで格納しているとin句は使えな いと知りました。。
テーブルにカンマ区切りで格納することは、 変えることはできませんし、 SQLで1回で取得しなきゃいけないのです。
そんなこと、可能なのでしょうか。。
明日の朝までに教えていただければ、
すごくすごく助かります。。
すみませんが、宜しくお願いします。
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.5
- 回答日時:
#3 ですが、商品IDが2桁以上になるとダメですね。
マッチングに正規表現を使わなければならないかも知れません。
SELECT
no,
(SELECT LISTAGG(商品名, ', ') WITHIN GROUP (order by 商品ID) FROM Bテーブル b WHERE
REGEXP_LIKE(a.商品ID, '\s*(.*\D)?' || b.商品ID || '(\D.*)?\s*')
FROM Aテーブル a;
参考URL:http://docs.oracle.com/cd/E16338_01/appdev.112/b …
No.4
- 回答日時:
> 呼び出し元(php)で Aテーブルのカンマ区切りの値を
> 取得→再度その値を元にSQLを組んでBテーブルの
> 取得、という感じがいいということでしょうか?
一番単純な方法はそうですが、データ量によっては物凄く
遅くなります。『Bテーブルの取得』の回数は、なるべく少なく
なるように工夫したほうが良いでしょう。
A案)
Bテーブルのデータが十分少ない(300件くらい)場合:
Bテーブルのデータを最初に全て取得して、PHP 側で
『商品ID=>商品名』 の配列で持っておく。そして、A
テーブルの商品IDはこの配列を使って変換する。
⇒ この方法なら、Bテーブルへのアクセスは1回だけ
B案)
Bテーブルのデータが多いけど、実際に使われる商品の
種類は少ない場合:
Bテーブルから取得した結果を、『商品ID=>商品名』の
配列に貯めていく。Aテーブルの商品IDの変換は、まず
配列で変換して、配列になければ Bテーブルから取得
する。(Bテーブルから取ったデータは、次のデータのため
に配列に入れておく)
⇒ この方法なら、BテーブルへのアクセスはAテーブルの
商品の種類の数だけ
いずれもキャッシュ(配列)を使った、処理速度アップの常套
手段です。
No.3
- 回答日時:
Oracle 11g R2 以降で使える LISTAGG 関数を使えば出来るかも知れません。
かなり強引ですが・・・。(それ以前のバージョンでも wmsys.wm_concat という同じ事をする隠し関数は有ったみたいです)
SELECT
no,
(SELECT LISTAGG(商品名, ', ') WITHIN GROUP (order by 商品ID) FROM Bテーブル b WHERE a.商品ID LIKE '%' || b.商品ID || '%') AS 商品名
FROM Aテーブル a;
なお、手元にOracleが無いので動作は未確認です。
参考URL:http://www.shift-the-oracle.com/sql/aggregate-fu …
No.1
- 回答日時:
SQL1回で取るのは不可能です。
どうしてもDBへの呼出し1回で取る必要があるのであれば、
ストアドプロシージャを組むしかありません。
以下のような文字列切り出し関数を応用して作ることになり
ます。
http://www.shift-the-oracle.com/sql/functions/st …
ぶっちゃけ敷居が高いので、呼出側で処理できないか (複数
回の呼出しを許容できないか) 真面目に検討したほうが良い
です。
# 言っても詮無いことですが、このような DBの基本をガン無
# 視するようなデータの格納方法をするのがそもそもの間違
# いです。これで処理が簡単にできるわけがありません。
#
# 正直なことを言わせて頂くと、今後もデータを取得する SQL
# を作るたびに苦労するのは火を見るより明らかなので、カン
# マを使わないデータを入れるテーブルを別に作っておいた
# ほうが良いです。
さっそく詳しくしくご回答をいただき、本当に感謝です!
やはり、無理ですか。。
調べてみても考えてみてもできる気がしなくて、でも確信できずに途方にくれてました
。
ストアドプロシージャでできるのですね!
調みてみます!
もし1回呼び出しにこだわらなければ、
呼び出し元(php)で
Aテーブルのカンマ区切りの値を取得→再度その値を元にSQLを組んでBテーブルの取得、という感じがいいということでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「マスタ」と「テーブル」の違...
-
主キーの変更
-
商品コード番号を入力すると商...
-
2つのテーブルから条件に一致...
-
重複するキーから一番古い年月...
-
Accessでフィールドを比較した...
-
PLSQLの識別子エラー
-
ACCESS インポート時の重複チ...
-
ACCESSのSQLで、NULLかNULLでな...
-
3つ以上のテーブルをUNIONする...
-
SI Object Browserのテーブルス...
-
SELECT時の行ロックの必要性に...
-
ACCESS2007 フォーム 「バリア...
-
ビューで引数を使いたい
-
データの二重表示の原因
-
IDENTITY列
-
accessのエクスポートエラーに...
-
sqlserverで集計結果をUPDATEし...
-
Access VBA [リモートサーバー...
-
既に使用されているので、使用...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「マスタ」と「テーブル」の違...
-
2つのテーブルから条件に一致...
-
重複するキーから一番古い年月...
-
主キーの変更
-
update文で質問です。 下記の条...
-
ACCESS 一つのフィールドに複...
-
続.ORACLEのSELECTのソートに...
-
accessで移動平均する方法
-
行方向のデータを横に並べる
-
Accessでフィールドを比較した...
-
PLSQLの識別子エラー
-
商品コード番号を入力すると商...
-
ACCESSのデータシート形式のフ...
-
複数InnerJoin時の処理落ち回避法
-
Accessのテーブル設計について...
-
正規化・リレーションシップに...
-
Accessのコンボボックスの使い...
-
データベースの問題
-
ACCESSのコンパイルエラーについて
-
SQL結合条件
おすすめ情報