• 締切済み

履歴データの最終行の抽出

受注テーブル(tbl_Jyutyu)に対する、出荷履歴テーブル(tbl_Rireki)の内、最終行を取得したい。 現在は、以下の様なクエリーで、出荷履歴テーブルの自分自身の出荷回数(intKaisuu)が、最大値の行を集めている。 出荷がない(レコードがない)データもあるため、左方結合している。 目的のデータは出力できるの、速度が出ないためもっといい方法があれば、教えて頂きたいと思い投稿しています。 select J.intJyutyuNo, ... , R.datSyukkaDay from tbl_Jyutyu J left outer join tbl_Rireki R on R.intJyutyuNo = J.intJyutyuNo and R.intKaisuu = (select max(intKaisuu) from tbl_Rireki R2 where R2.intJyutyuNo = R.intJyutyuNo) where J.intJyutyuNo > 0 実際にはもっと複雑で、受注に対する明細、また、発注テーブル等との結合しています。 (これも発注無しデータもあるため左方結合しています。) データ件数は受注数十万件、明細行数百万件あるため、条件によっては、タイムアウトしてしまう。 left outer join が原因、そもそもテーブル設計に問題があるのかも知れませんが、その変更は現在できません。 地道に、速度アップするようにクエリー変更しています。同じクエリーでも、テストデータと現場データでは、 速度が逆転してしまい、苦労しています。 どなたかアドバイス頂ければ幸いです。よろしくお願い致します。

  • amfm
  • お礼率50% (1/2)

みんなの回答

  • hidebu-
  • ベストアンサー率53% (45/84)
回答No.1

いくつか方策はありますが、 あまりにも情報が大雑把なので答えようがないと思います。 チューニングの観点から助言を求めるのであれば、各テーブルのキーや外部キー、データ型がわからないとなんともいえませんし、もちろんSQL全文がないと答えようがありません。 また、 システムアーキテクチャの観点から助言を求めるのであれば実行環境はもちろん、今回の求めたい結果がデータハウスとしての運用されるのか?、それともOLAPの業務運用の一環にもちいられるのか? どこまでリアルタイム性が求められるのか? 等がわからないと答えようがありません。 要件と制約といったシステム全体がわからない第三者が 仕様の一部だけを抜き出して提示され、最適化したいと問われたところで助言をすることは不可能だと思われます。

amfm
質問者

補足

hidebu-さん、ご回答ありがとうございます。 情報が大雑把で申し訳ありません。 データウェアハウスやOLAPと言ったものは利用していません。MSSQL Server7で単一のデータベース内での運用です。 要件と制約と言われると、どのように説明すればいいのか分からないのですが。 完全にリアルタイムで、検索する必要があります。検索条件を入れて検索のアクションで、動的にクエリーを作成しています。 目的は、分析ではなく、多くの場合には、特定の一件を検索。また多くても数十件の検索することです。 顧客名や電話番号、商品コードや出荷日等を条件として絞り込みます。 受注データ(1受注、1明細)が先に作成され、この受注データに対して、受注番号を持った顧客、出荷、発注等の別テーブルにレコードが後から作成される。 顧客や出荷データが無くても、受注を出力する必要があるため、left outer join のオンパレード、遅くなっても仕方が無い状態です。 ごめんなさい。余計に分かりづらい、概要説明になってしまいました。 他方に無い行を出力するには、left(right) outer join しかないですよね。最近あきらめモードになっています(^^; どうも、ありがとうございました。

関連するQ&A

  • ACCESSとORACLEで抽出結果が異なる

    いつもお世話になっております。 ACCESS2000を扱っております。 ACCESSのデータベースにODBCを接続してORACLEの テーブルをリンクテーブルとしてインポートします。 そして、ACCESSのテーブルとORACLEのテーブルを LEFT JOIN を行いクエリーを作成したのですが、 正しい結果が抽出できません。 ただし、ORACLEのテーブル構成・データと全く同一の ACCESSのテーブルを作成し、クエリーを作成したところ 正常に動作しております。 SQLは以下のような内容となっております。 sSQL = SELECT TBL_1.A, TBL_1.B, TBL_1.C FROM TBL_1 LEFT JOIN TBL_2 ON TBL_1.A = TBL_2.A AND TBL_1.B = TBL_2.B AND TBL_1.C = TBL_2.C WHERE TBL_2.A IS NULL AND TBL_2.B IS NULL AND TBL_2.C IS NULL TBL_1がORACLEより引っ張ってきたリンクテーブル、 TBL_2がACCESSに存在するテーブルになります。 以上のSQLで、TBL_2に存在なくTBL_1に存在するレコード、及びTBL_1とTBL_2でキー項目は同じだが 内容が異なるレコードを抽出できると考えているのですが、TBL_2に存在なくTBL_1に存在するレコードしか 抽出できません。 個人的には、処理する件数が多大であることが影響しているのかとも考えているのですが・・・。 (両テーブルともに約20万件レコード) クエリーを分割することで解決はしたのですが、 原因究明を求められておりまして大変困っています。 皆様の知恵を借りたいです。宜しくお願いいたします。

  • 1SQLで書けないものでしょうか

    初めて投稿します。 よろしくお願いします。 現状、下記の様な構成のテーブルがあります。 DB :oracle9iR2 テーブル名:test 名前 型 ------- ------------- key_data VARCHAR2(10) rireki DATE read_data VARCHAR2(10) プライマリキーは、key_dataとrirekiです。 この、データの中から、key_data毎に最新のrirekiの情報だけを 取得したいと考えています。 そこで、下記の様にクエリーを組んでいたのですが、 select key_data, rireki, read_data from test inner join ( select key_data, max(rireki) AS rireki from test group by key_data ) test2 on (test.key_data = test2.key_data and test.rireki = test2.rireki) 複数のテーブルが、上記の様なキー項目と履歴を持つ形で 構成されている為に、複数のテーブルを結合すると途端に パフォーマンスが落ちて困っています。 ひょっとしたら、oracleなら分析関数か何かで1SQLで書けないものか (それで、処理速度が向上出来れば)と云うことで、自分で調べて みましたが、良い方法が見つかりません。 同様のお悩みをもたれた方で、対処法がありましたら教えていただけると幸いです。 よろしくお願いいたします。

  • Access クエリ 抽出・演算

    Access クエリについてご質問させていただきます。 テーブルのデータを特定の条件に一致するレコードだけ抽出し、演算を実施したいです。 (1):CSVデータをテーブルに取り込みます。 テーブルは左から『取引No』『部門コード』『部門名』『発注入力日』『担当者名』『発注日』『伝票No』『伝票行No』『商品コード』『商品名』『入数』『発注数(入力数)』『発注数量※1』『発注金額※2』『出荷日』『出荷数量※3』『出荷金額※4』となっております。 ※1:発注数量は入数×発注数が計算済みです。 ※2:発注金額は発注数量×単価で小数点以下切り捨てで計算済みです。 ※3:出荷数量は入数×出荷数が計算済みです。 ※4:出荷金額は出荷数量×単価で小数点以下切り捨てで計算済みです。 (2):クエリを使用して、商品名が『単3乾電池』の出荷数量を10で割り、10で割り切れるレコードを求めたいです。 (3):(2)の演算結果(10で割った後の整数)を合算して合計値をクエリの演算結果として表示したいです。 ※(2)の抽出条件でのクエリをすでに作成済みで、合計したクエリを作成したいです。 どのようにすればよろしいでしょうか?

  • MAX関数を使ってからLEFT JOINしたいのですが・・

    毎度お世話になります。 下記2つのテーブルからテーブル結合をして表示させたいのですが、その前にサブテーブルにある時間データの中で最新のものだけと結合したいと考えています。色々試したのですがうまくいきません。どなたかご教授の程よろしくお願いいたします。 main_tbl | id | basyo | name | --------------------- | 1 | 1  | aa  | | 2 | 1  | bb  | | 3 | 2  | cc  | | 4 | 3  | dd  | sub_tbl | id | jyotai | time  | ------------------------ | 1 | 1   |12:25:30| | 1 | 2   |13:15:12| | 2 | 1   |13:20:14| | 1 | 3   |13:50:08| 欲しい結果 | id | basyo | name | jyotai | time | --------------------------------------- | 1 | 1  | aa  | 3   |13:50:08| | 2 | 1  | bb  | 1   |13:15:12| | 3 | 2  | cc  | null  | null | | 4 | 3  | dd  | null  | null | 考えた構文 $sql = "SELECT main_tbl.id, main_tbl.basyo, main_tbl.name, sub_tbl.jyotai, sub_tbl.time FROM main_tbl LEFT OUTER JOIN (SELECT MAX(time) FROM sub_tbl GROUP BY id) ON main_tbl.id = sub_tbl.id"; または $sql = "SELECT main_tbl.id, main_tbl.basyo, main_tbl.name, sub_tbl.jyotai, sub_tbl.time FROM main_tbl LEFT OUTER JOIN sub_tbl on main_tbl.id = sub_tbl.id WHERE SELECT MAX(time) FROM sub_tbl GROUP BY id"; または $sql1 = "SELECT MAX(time) FROM sub_tbl GROUP BY id"; $rs1 = mysql_db_query($db,$sql1) or die("sql Error!"); $sql = "SELECT main_tbl.id, main_tbl.basyo,main_tbl.name, $rs1.jyotai, $rs1.time FROM main_tbl LEFT OUTER JOIN $rs1 ON main_tbl.id = $rs1.id"; ~以下クエリの実行と表示文~ どれも駄目でした。(クエリエラー表示) 因みに結合のみとMAX関数を別々に実行すると表示できることを確認しています。 環境は WinXP Mysql5.0.41 php5.2.3 です。 まだまだ勉強中ですのでよろしくお願いいたします。

    • ベストアンサー
    • PHP
  • Left outer join とかのLeft

    Left outer join とright outer join ですが、解説などをみると、左右に表が描かれてあって、線を引いたりして結合していくのですが、 何をもって左とか右とかいうのでしょうか? テーブル1が左で、テーブル2が右みたいな感じで解説されるのですが、先に出てきた1も、あとに出てきた2も、単に出てきた順番であり、記号と思われます。1と2を入れ替えたら同じことです。Left outer join Table1 もRight outer join Table2 も同じことのように思われます。私はなにか勘違いしているのでしょうか?

  • テーブルを結合する構文はUNIONやJOINがありますが

    テーブルを結合する構文はUNIONやJOINがありますが この場合クエリー速度は1本のテーブルと複数のテーブルではどの程度 違うのでしょうか? また物理的に複数のテーブルを1つにしたい場合に何かいい方法は ないでしょうか。

    • ベストアンサー
    • MySQL
  • データ無し時は空白行にしたい【SQLITE】

    こんにちは 日時とその時の人数データを格納しているテーブルがあり 日付をキーに0時から23時までのデータを獲得するのですが データが存在しない時刻があり、 その時刻はブランク(NULL)で表示したいです。 外部結合とやらで実現できそうと思い、 <テーブル構成> 人数データテーブル(CNT_DATA) 日時、人数 ブランク行用テーブル(BLANK_DATA) 時(00~23) SELECT B.時,C.人数 FROM BLANK_DATA B LEFT OUTER JOIN CNT_DATA C ON B.時 = strftime('%H',C.日時+2415018.5) WHERE C.日時による範囲指定 とやったのですが、 CNT_DATAに存在する時刻行しか引っ張ってこず、 ブランク行ができません。 根本的に考え方が違う様に思えてきているのですが、 どなたか教えていただけないでしょうか?

  • 複数の外部結合

    こんにちは、外部結合の仕方についてお聞きしたいのですが、 このSQL1で抽出されたデータにさらに TABLE3テーブルのデータを追加したくSQL2を作成したのですが、 うまくいきません。 ON TABLE1.[Code]=TABLE3.[Code]の部分をどのように記述すればよいのでしょうか? SQL1--------- TABLE1.[tamp] [Child], TABLE2.* FROM [p].[Price] TABLE1 LEFT OUTER JOIN [p].[Receive] TABLE2 ON TABLE2.[Code]=TABLE1.[Code] SQL2---------- TABLE1.[tamp] [Child], TABLE2.*, TABLE3.* FROM [p].[Price] TABLE1 LEFT OUTER JOIN [p].[Receive] TABLE2 ON TABLE2.[Code]=TABLE1.[Code] LEFT OUTER JOIN [p].[Product] TABLE3 ON TABLE1.[Code]=TABLE3.[Code]

  • Access 抽出漏れ行をみつけるクエリ

    図のようなテーブル「TBL_A」がCSVファイルの形で提供されます。この「TBL_A」は全レコードのテーブルあり「正」データばかりのマスターと考えてください。 このCSVデータをACCESSによみこみテーブル「TBL_A」としてあります。 「TBL_A」をいろいろな人が加工したり、抽出作業をしているのですが、「TBL_B」のような抽出をかけて渡してきた人がいたので、「データ(レコード)が足りないので、不一致クエリで足りないのを見つけておいてください」と頼んだところ、何度やってもみつけられないというので、自分でも試してみました。 図でいえば、ピンク色のレコード(行)をみつければいいのですが、Accessで不一致クエリをかけてみたところ、図の下部のようなデータしか抽出できませんでした。 やったことは2つ 1) TBL_Aを左にし、右にTBL_Bを右に配置し、不一致クエリウィザードでの矢印(→)で商品コードを紐付けた 2) 最初にTBL_AとTBL\Bをクエリで「商品コード」「価格」ぞれぞれ結びつけ(つまり2つの線)、「商品コード」「価格」を「クエリ1」として抽出。その「クエリ1」を上のTBL_Bの位置にもってきて、不一致クエリ。 どちらとも、結果は図の下のようになってしまいます。 図の上部のピンクの部分を確実に抜き出すには、どのようなクエリ(またはSELECT文)が必要でしょうか。 メモ: ・商品コードは「テキスト型」です。 ・商品コードが同じでも販売場所やいろいろな経緯で価格が違っていたり、返品の場合は返金するためマイナス金額がつくことがあり、商品コードと価格はかならずしも合致しません。 ・Accessは2010か2013を使っています。 ※今回はVBAの質問ではありません。

  • データ型の変更

    アクセス2003を使っています。 ユニオンクエリを使って複数のクエリを結合しました。 その後、SQLで結合したクエリをテーブルにする為、 SELECT Qユニオンクエリ.* INTO T統合 FROM Qユニオンクエリ; という、SQLを使ってテーブルにしました。 できあがったテーブルのデータ型が希望通りになっていないので、 データ型を変更して、常にそのデータ型で処理したいので保存しておきたいと思います。 しかし、データを入れる度に、前述のユニオンクエリを使い、再びそのクエリをテーブルにするという処理を行います。 その際にデータ型がまた変わってしまいます。 対処方法はあるでしょうか? よろしくお願いします。