- PR -

SQL文の組み方

投稿者投稿内容
ryo
会議室デビュー日: 2006/12/16
投稿数: 4
投稿日時: 2006-12-16 18:21
はじめまして。ryoと申します。

使用DB:oracle10g

品目コードと値段と値段変更日の登録してある値段テーブルから
マスタテーブルのコードを使って、現在の日付より前の値段を
各コードごとに拾って、値段・コード・名称を一レコードとして
データを取得したく、SQLを組んで見たのですが
下記の方法だと上手くいきません。
副問い合わせの中で外側の情報(ms.コード)を使うのは無理がありますか?
また、他にこういったレコードを取得する方法がありますでしょうか?

以上、宜しくお願い致します。


SELECT
(SELECT NE.値段
FROM (select ne2.値段 from 値段テーブル ne2 WHERE ms.コード = NE.品目コード AND
ne2.値段変更日 <= sysdate order by ne2.値段変更日 desc) NE WHERE rownum = 1) ,
ms.コード
ms.名称
from 品目マスタ ms

saki1208
ベテラン
会議室デビュー日: 2006/08/22
投稿数: 86
投稿日時: 2006-12-16 19:10

saki1208です。

引用:


SELECT
(SELECT NE.値段
FROM (select ne2.値段 from 値段テーブル ne2 WHERE ms.コード = NE.品目コード AND
ne2.値段変更日 <= sysdate order by ne2.値段変更日 desc) NE WHERE rownum = 1) ,
ms.コード
ms.名称
from 品目マスタ ms




ネストしたクエリ内で、自分の親よりも上位のクエリの項目は、参照できないと思います。

この場合は、「Row_Number()」を使用すればできるかと...
「Row_Number()」については、リファレンスを参照してください。
でっち6号
大ベテラン
会議室デビュー日: 2005/01/31
投稿数: 176
お住まい・勤務地: Kawasaki
投稿日時: 2006-12-16 20:31
こんにちは、でっちです。

引用:

saki1208さんの書き込み (2006-12-16 19:10) より:

ネストしたクエリ内で、自分の親よりも上位のクエリの項目は、参照できないと思います。


Oracle10gなら問題なく可能ですけど...

ryoさん
「上手くいきません」と言われても困ってしまいます。
エラーになってしまうのですか?望む結果が得られないのですか?
エラーになっているのであれば、どのようなメッセージが表示されていますか?

エラーになってると仮定すると、問題なのは「ms.コード」じゃなくて 「NE.品目コード」の方じゃないかと思われます。
「ne2.品目コード」に変えてみたらどうなりますか?
ryo
会議室デビュー日: 2006/12/16
投稿数: 4
投稿日時: 2006-12-17 10:17
返答ありがとうございます。


>でっちさん
すみません。NE.品目コードは作成していたSQLからわかりやすく置き換えたときに間違えましたorz
実際はne2.品目コードと同じ形になっていました。

それで
(SELECT NE.値段
FROM (select ne2.値段 from 値段テーブル ne2 WHERE ms.コード = NE.品目コード AND
ne2.値段変更日 <= sysdate order by ne2.値段変更日 desc) NE WHERE rownum = 1)
この部分は狙ったデータが取れていたので
もう一度、1から組み直してみたら、ちゃんとデータを取ってこれました。
お騒がせして申し訳ないです。

実際データを取得していたSQLに上記を組み込んだら「ORA-03113: 通信チャネルでend-of-fileが検出されました」となってしまっていたので、ここに問題があると思い込んでいて、他の部分との兼ね合いを見ていませんでしたorz


>saki1208さん
「Row_Number()」は知らなかったので、これを使ったやりかたも練ってみたい思います。
ryo
会議室デビュー日: 2006/12/16
投稿数: 4
投稿日時: 2006-12-17 11:30
orz

出来たと思ってたら取れたデータは値段が全部同じになってました。

値段  コード      名称
1111 2006090101 a
1111 5001001    b
1111 3222        c


レコード毎にms.コードを読んでくれないのでしょうか?

[ メッセージ編集済み 編集者: ryo 編集日時 2006-12-17 11:31 ]

[ メッセージ編集済み 編集者: ryo 編集日時 2006-12-17 11:32 ]
saki1208
ベテラン
会議室デビュー日: 2006/08/22
投稿数: 86
投稿日時: 2006-12-17 21:37

saki1208です。

なんと、10gではできるとは...
現在まで、9iまでしか使用していないもので...

自分で試してから返信したわけではなかったので、わかりませんでしたが、
Row_Number()を使用しても結果は同じかも...

グレハン
常連さん
会議室デビュー日: 2006/02/23
投稿数: 25
投稿日時: 2006-12-18 15:29
10gがないので動作確認はできてませんが

コード:
SELECT
   M.コード
  ,M.名称
  ,ISNULL(S.値段,0) 値段
FROM 品目マスタ M
LEFT JOIN 
    (
    SELECT
       A.値段
      ,A.品目コード
    FROM 値段テーブル A
    INNER JOIN
        (
        SELECT
           MAX(値段変更日) 値段変更日
          ,品目コード
        FROM 値段テーブル
        WHERE 値段変更日 <= sysdate
        GROUP BY 品目コード
        ) B
    ON A.値段変更日 = B.値段変更日 AND A.品目コード = B.品目コード
    ) S
ON M.コード = S.品目コード



でどうでしょう?
でっち6号
大ベテラン
会議室デビュー日: 2005/01/31
投稿数: 176
お住まい・勤務地: Kawasaki
投稿日時: 2006-12-18 18:27
BBコードの"code"を使うと表を作る時にズレなくて楽ですよ
コード:
値段   コード          名称
1111   2006090101      a
1111   5001001         b
1111   3222            c



引用:

ryoさんの書き込み (2006-12-17 11:30) より:
orz

出来たと思ってたら取れたデータは値段が全部同じになってました。
レコード毎にms.コードを読んでくれないのでしょうか?



あー、2段階ネストするとだめだったかな??
でもその時はORA-00904あたりが発生しそうですが...
現在の動きは、コード連結がないときの結果みたいですね。
再度組み直したSQLをさらした方が解決は早いように思われます。

逆方向の連結の方が簡単なので、まずそちらを書いてみれば、できることは確認できると思います。
コード:
select ne2.値段, ne2.品目コード,
(select ms.名称 from 品目マスタ ms WHERE ms.コード = ne2.品目コード )
 from 値段テーブル ne2
 WHERE ne2.値段変更日 = (SELECT MAX(ne3.値段変更日) FROM 値段テーブル ne3
 where ne2.品目コード=ne3.品目コード and ne3.値段変更日 <= sysdate)



ちょっと技術的な裏はとれてないので不確実ですが、2段階のネストがNGの場合、
ms.コードを使う箇所を1段階上に持っていくとどうでしょう?
コード:
SELECT 
(SELECT NE.値段 
FROM (select ne2.値段, ne2.品目コード from 値段テーブル ne2
 WHERE  
ne2.値段変更日 <= sysdate order by ne2.値段変更日 desc) NE
 WHERE ms.コード = NE.品目コード 
 AND rownum = 1) , 
ms.コード 
ms.名称 
from 品目マスタ ms



ついでに書くと、joinを使うやり方もあります。
#って書こうとしたらかぶったのでやめ。
#同じ日に値段変更してたらレコード数が増えるからNGかな?

スキルアップ/キャリアアップ(JOB@IT)