• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:サブクエリの書き方)

サブクエリを使って受注数量と単価Mの照合を行う方法

このQ&Aのポイント
  • 受注Tテーブルと単価Mテーブルの照合において、受注時に単価Mにデータがない場合はNULLを入れる方法を説明します。
  • 単価照合VというVIEWを作成し、受注Tテーブルの単価部分を単価Mテーブルと照合させます。
  • SQLのサブクエリを使って、受注数量と受注日を条件に照合を行い、適切な単価を取得します。

質問者が選んだベストアンサー

  • ベストアンサー
  • root139
  • ベストアンサー率60% (488/809)
回答No.2

受注Tの単価がNULLの場合だけ単価Mから単価を引っぱってきたいという事ですよね? 単価Mの抽出条件としては、製品CD・得意先CDが受注Tと同じで、数量FROMと数量TOの範囲が受注Tの数量を含んでおり、適用日が受注Tの受注日以前で最新のものとなります。 例) ------------------------------------------ SELECT  製品CD,  得意先CD,  数量,  COALESCE(   単価,   (SELECT TOP 1 単価 FROM 単価M TK WHERE    JC.製品CD = TK.製品CD AND JC.得意先CD = TK.得意先CD AND    JC.数量 BETWEEN TK.数量FROM AND TK.数量TO AND    TK.適用日 <= JC.受注日    ORDER BY TK.適用日 DESC   )  ) AS 単価,  受注日 FROM 受注T JC; ---------------------------------------------- OLAP関数を使えばもう少しスッキリするかも知れません。

5S6
質問者

お礼

遅くなり申し訳ありません。 できました。 こんな書き方があったんですね。

その他の回答 (3)

  • innoya
  • ベストアンサー率71% (10/14)
回答No.4

こんにちは。 下記の私の回答に少し間違いがありました。 「root139」さんの回答が正しいですね。 大変失礼いたしました。 よろしくお願い致します。

  • innoya
  • ベストアンサー率71% (10/14)
回答No.3

こんにちは。 下記のSQLのようにしてみてください。 簡単にできると思います。 SELECT A.SIdx, A.TIdx, A.Cnt , CASE WHEN A.Amount IS NULL THEN B.Amount ELSE A.Amount END AS Amount , A.RegDate FROM #TableT A WITH (NOLOCK) LEFT OUTER JOIN #TableM B WITH (NOLOCK) ON A.SIdx = B.SIdx AND A.TIdx = B.TIdx AND A.Cnt >= B.CntFrom AND A.Cnt < B.CntTo 上記のSQLをテストするために質問内容を元に下記のSQLを準備しました。 実際に実行してご確認してください。 -- #### 一時テーブル作成 CREATE TABLE #TableT ( SIdx varchar(10) ,TIdx varchar(10) ,Cnt int ,Amount int ,RegDate datetime ) GO CREATE TABLE #TableM ( SIdx varchar(10) ,TIdx varchar(10) ,CntFrom int ,CntTo int ,Amount int ,RegDate datetime ) GO -- #### データ登録 INSERT INTO #TableT SELECT '0001', '2001', 500, 3000, '2013/7/5' UNION ALL SELECT '0002', '2002', 1000, NULL, '2013/9/25' UNION ALL SELECT '0003', '2003', 1800, NULL, '2013/9/25' GO INSERT INTO #TableM SELECT '0001', '2001', 0, 99999, 3000, '2013/5/1' UNION ALL SELECT '0002', '2002', 0, 500, 800, '2013/5/1' UNION ALL SELECT '0002', '2002', 501, 999999, 500, '2013/5/1' UNION ALL SELECT '0003', '2003', 0, 500, 2000, '2013/1/1' UNION ALL SELECT '0003', '2003', 501, 999999, 1800, '2013/1/1' UNION ALL SELECT '0003', '2003', 0, 500, 2500, '2013/9/20' GO -- #### 結果 SELECT A.SIdx, A.TIdx, A.Cnt , CASE WHEN A.Amount IS NULL THEN B.Amount ELSE A.Amount END AS Amount , A.RegDate FROM #TableT A WITH (NOLOCK) LEFT OUTER JOIN #TableM B WITH (NOLOCK) ON A.SIdx = B.SIdx AND A.TIdx = B.TIdx AND A.Cnt >= B.CntFrom AND A.Cnt < B.CntTo

5S6
質問者

お礼

ありがとうございました。 ODBC経由読み取り専用アカウントなのでテーブル作成ができません。 でもこんなやりかたもあるんですね。 テンポラリテーブルは、削除しなくても勝手に消えるんでしょうか?

回答No.1

SELECT 受注T.製品CD, 受注T.得意先CD, 受注T.数量, NULL, 受注T.受注日 FROM 受注T WHERE NOT EXISTS ( SELECT * FROM 単価M WHERE 受注T.製品CD = 単価M.製品CD AND 受注T.得意先CD = 単価M.得意先CD AND 受注T.数量 >= 単価M.数量FROM AND 受注T.数量 <= 単価M.数量TO AND 受注T.受注日 >= 単価M.適用日 ) UNION ALL SELECT 受注T.製品CD, 受注T.得意先CD, 受注T.数量, 単価M.単価, 受注T.受注日 FROM 受注T, 単価M WHERE 受注T.製品CD = 単価M.製品CD AND 受注T.得意先CD = 単価M.得意先CD AND 受注T.数量 >= 単価M.数量FROM AND 受注T.数量 <= 単価M.数量TO AND 受注T.受注日 >= 単価.適用日 AND (EXISTS ( SELECT * FROM 単価M M2 WHERE 受注T.製品CD = M2.製品CD AND 受注T.得意先CD = M2.得意先CD AND 受注T.数量 >= M2.数量FROM AND 受注T.数量 <= M2.数量TO AND 受注T.受注日 < M2.適用日 ) OR NOT EXISTS ( SELECT * FROM 単価M M2 WHERE 単価M.製品CD = M2.製品CD AND 単価M.得意先CD = M2.得意先CD AND 単価M.数量 >= M2.数量FROM AND 単価M.数量 <= M2.数量TO AND 単価M.適用日 < M2.適用日 ) ) こんな感じ? すごい脊髄反射的な回答になりましたが。

5S6
質問者

お礼

遅くなり申し訳ございません。 ありがとうございました。

関連するQ&A