• ベストアンサー

解けずにおりますクエリの解をご教授下さい。

以下定義のレコードを基準日毎に処理をして行きます。 処理の途中で変更フラグに"9"が出現した時、項目1が同一である 基準日~銘柄コード項目に付いて、直前レコードの値を取得したいのですが。 以下の場合ですと、アスタリスクの項目1の値を持つ最新のレコードは アットマークのレコードになります。 従いまして"080613|1|001|CD0002"を取り出したいのですが。 ちなみに基準日~銘柄コードはキー項目の為、一意になっています。 いろいろ試しましたが、上手く取り出せません。 ご教授下さいます様、よろしくお願いいたします。 環境:SQL Server2005 基準日|変更フラグ|連番|銘柄コード|項目1 080612|1|001|CD0002|01010101 @ 080613|1|001|CD0002|01010101 080614|1|001|CD0001|11001100 080614|1|002|CD0002|11111111 080615|1|001|CD0001|10101010 * 080615|9|002|CD0002|01010101 080615|1|003|CD0002|01010100

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

  • ベストアンサー
回答No.1

>基準日~銘柄コード項目に付いて、直前レコードの値を取得したいのですが。 >以下の場合ですと、アスタリスクの項目1の値を持つ最新のレコードは >アットマークのレコードになります。 >従いまして"080613|1|001|CD0002"を取り出したいのですが。 「直前」とか「最新」というのが曖昧ですが? どちらも、@の行のことを指してますよね? >ちなみに基準日~銘柄コードはキー項目の為、一意になっています 提示されたデータ例を見る限り、標準日+連番だけで一意になるようですが? 曖昧な部分がありますが、「標準日+連番だけで一意になる」と解釈し、SQL例を示します。 SQL Server 2005から実装された、Oracleでいう分析関数を使った例です。 もう少し効率的にできるのですが、曖昧な部分があるので取りあえずこの段階で提示しておきますので参考にしてください。 <SQL例> select y.* from (select koumoku1 from t1 where henko='9') as x, (select *, row_number() over(partition by koumoku1 order by kijunbi desc,renban desc) as rn from t1) as y where x.koumoku1=y.koumoku1 and rn=2 order by y.koumoku1

ken__t
質問者

お礼

お礼が遅れまして、大変失礼致しました。 row_number~の箇所から以下のアイデアが思いつきました。 order by句で基準日,連番を新->旧になる様"desc"指定し、 select時に"top 1"とで最初の1件を取り出す。 見事に期待通りの結果が得られました。 恐らく、自分の回答をご覧になられて、 「それを求める質問だったのかよ。だったらその回答、とっくに思い付いていたよ」 と思われましたら、説明が下手でしたこと、申し訳御座いません。 しかし、そこを酌んで頂き、大変なヒントとなりました。 これからはもう少し、相手に伝わる様に心がけるように致します。 有難う御座いました。

その他の回答 (2)

  • plutoscp
  • ベストアンサー率0% (0/1)
回答No.3

質問者の内容とおり、以下のテーブルを作成しました。 CREATE TABLE [dbo].[対象テーブル]( [Seq] [bigint] IDENTITY(1,1) NOT NULL, [基準日|変更フラグ|連番|銘柄コード|項目1] [varchar](50) NOT NULL, ) INSERT INTO 対象テーブル select '080612|1|001|CD0002|01010101' union select '080613|1|001|CD0002|01010101' union select '080614|1|001|CD0001|11001100' union select '080614|1|002|CD0002|11111111' union select '080615|1|001|CD0001|10101010' union select '080615|9|002|CD0002|01010101' union select '080615|1|003|CD0002|01010100' CREATE FUNCTION CTE() RETURNS @TEMP TABLE ( 基準日 varchar(6), 変更フラグ varchar(1), 連番 varchar(3), 銘柄コード varchar(6), 項目1 varchar(8) ) AS BEGIN declare c1 cursor for select [基準日|変更フラグ|連番|銘柄コード|項目1] as str_A from 対象テーブル declare @wk_str varchar(50) declare @wk_基準日 varchar(6), @wk_変更フラグ varchar(1), @wk_連番 varchar(3), @wk_銘柄コード varchar(6), @wk_項目1 varchar(8) open c1 fetch next from c1 into @wk_str WHILE @@FETCH_STATUS = 0 begin set @wk_基準日 = substring(@wk_str,1,6) set @wk_変更フラグ = substring(@wk_str,8,1) set @wk_連番 = substring(@wk_str,10,3) set @wk_銘柄コード = substring(@wk_str,14,6) set @wk_項目1 = substring(@wk_str,22,8) insert into @TEMP(基準日, 変更フラグ, 連番, 銘柄コード, 項目1) values (@wk_基準日, @wk_変更フラグ, @wk_連番, @wk_銘柄コード, @wk_項目1) fetch next from c1 into @wk_str end close c1 DEALLOCATE c1 RETURN END ※使い方↓とおり select * from cte() 上記を利用すればクエリを作成し、参照できるかとおもいます。 ご参照ください。

ken__t
質問者

お礼

お礼が遅れまして、大変失礼致しました。 No.1さんの回答からヒントを得まして、無事解決に至りました。 今後に役立つ内容が御座いましたので、勉強になりました。 有難う御座いました。

  • nfushi
  • ベストアンサー率31% (39/122)
回答No.2

では、私は別解を。 SELECT MAX(A.基準日)AS 最新日, A.変更フラグ, A.連番, A.銘柄コード, A.項目1 FROM No4108525 A INNER JOIN ( SELECT B.基準日, B.項目1 FROM NO4108525 B WHERE B.変更フラグ = 9 )C ON A.項目1 = C.項目1 WHERE A.基準日 < C.基準日 GROUP BY A.連番, A.変更フラグ, A.銘柄コード, A.項目1

ken__t
質問者

お礼

お礼が遅れまして、大変失礼致しました。 こちらでも期待値が得られました。 No.1さんのご回答で先に解決してしまいました。 しかし、こちらのご回答も今後に役立つ回答でしたので、大いに勉強になりました。 説明が下手な中、丁寧にご回答下さいまして有難う御座いました。

関連するQ&A

  • 数字のソート

    早速です。 以下のように頭に連番、 次の4項目が00~99までの数字の レコードがあります。 これを連番は崩さず、 4個の数字を昇順に並べたいのですが。 どのようにソート(コード)すれば宜しいでしょうか。 1<>8<>13<>27<>30<> 2<>20<>9<>1<>16<> 3<>5<>31<>36<>38<> 4<>52<>79<>18<>27<> 5<>23<>15<>9<>28<> 6<>38<>6<>45<>25<> ↓ 1<>8<>13<>27<>30<> 2<>1<>9<>16<>20<> 3<>5<>31<>36<>38<> 4<>18<>27<>52<>79<> 5<>9<>15<>23<>28<> 6<>6<>25<>38<>45<> 宜しくお願いします。

    • ベストアンサー
    • Perl
  • COBOLについて

    COBOLで以下のような仕様の場合、どのようなロジックにするのが良いでしょうか? ・仕様  A項目=値A または  B項目=値B または  (C項目=値C かつ D項目=値D ) または  E項目=値E 上記の場合、何も処理しない(以降の処理もせずに、次レコードを読みに行く  上記以外の場合、処理1を行い、次処理以降の処理を継続する。 (ロジック1) IF A項目=値A OR B項目=値B OR (C項目=値C かつ D項目=値D ) OR E項目=値E THEN CONTINUE ELSE 処理1を行う END-IF. (ロジック2) IF A項目=値A MOVE '1' TO 該当フラグ END-IF. IF B項目=値B MOVE '1' TO 該当フラグ END-IF. IF (C項目=値C かつ D項目=値D ) MOVE '1' TO 該当フラグ END-IF. IF E項目=値E MOVE '1' TO 該当フラグ END-IF. IF 該当フラグ='1' CONTINUE ELSE 処理1 END-IF. 自分は仕様に沿ってロジック1で組むべきだと思うのですが、 ロジック1は分かりずらいのとメンテが大変なのでロジック2で組むべきだと言われました。 どちらで組むのが普通でしょうか?どなたか教えて下さい!

  • インデックスの一意な値の数について

    インデックスを下記のように作成しているのですが、 MySQLはインデックスは同時に1つしか使用されないようなので どれを消そうか迷っています。 約177万件レコードがあるのですが、レコード数のうち 一意な値の数が何割以下ならインデックスを 張る意味がないといった基準はあるでしょうか? 一意な値の数 1.1772253(PK int型) 2.2338(idx int型) 3.1122(idx int型) 4.18(idx int型)

    • ベストアンサー
    • MySQL
  • Access2003 一つのクエリで結果を出したい

    お世話になります。 下記テーブルを紐付けてクエリを作成します(Access2003)。 受注テーブル  ・ID  ・コード  ・数量 検品テーブル  ・ID  ・コード  ・検品フラグ マスターテーブル  ・ID  ・コード  ・印刷フラグ 検品テーブルのレコードは、受注テーブルの数量合計が展開されたレコード数となります。例えば、AAAというコードで数量合計が8の場合、検品テーブルではAAAのレコードが8レコード存在することになります。 但し、マスターテーブルの印刷フラグがYesとなっているものは、数量がいくつあっても受注テーブルは1レコード作成されます(数量合計で展開しない)。  受注テーブル   ID コード 数量   1  AAA   5   2  AAA   3   3  BBB  100  検品テーブル   ID コード 検品フラグ   1  AAA   Yes   2  AAA   Yes   3  AAA   Yes   4  AAA   Yes   5  AAA   Yes   6  AAA   Yes   7  AAA   No   8  AAA   Yes   9  BBB   Yes  マスターテーブル   ID コード 印刷フラグ   1  AAA   No   2  BBB   Yes こんな感じです。 そこで各テーブルをコードで紐付けてグループ化し、検品フラグYesで抽出した状態で以下の結果を表示出来るようにしたいところです。 コード 数量合計  AAA   7  BBB  100 要するに印刷フラグがYesのものは受注テーブルの数量合計を表示し、それ以外は検品された数を表示させたいと考えています。 あらかじめ受注テーブルでコードでグループ化し、数量の合計を算出するクエリ(※1)を作成し、そのクエリと検品テーブル、マスターテーブルを紐付けたらうまく表示出来ました。 ※数量合計はIIFで印刷フラグ=Yesの場合は※1の数量合計を、Yesではない場合は検品テーブルのレコードカウント数を表示。 しかし、できれば一つのクエリで上記の結果を表示させたいのですが、可能なのでしょうか。 ご教授お願い致します。

  • エクセル関数について

    エクセルで以下の画像のとおり、項目の結果を出力したいのですが、どなたかご教示頂けないでしょうか。 項目コードの値と、フラグ0と1があらかじめ入力があります。 コードが同じ間フラグ0から1までの間は、結果が0から始まり+1ずつ加算されフラグ1で最後の数字になります。なみにフラグ0から1の間以外の空白について結果は空白になるようにしたいです。

  • Accessクエリの抽出条件

    Access2000を使用しています。 クエリの抽出条件にテーブルの値を使用したいのですが、その方法がわかりません。 テーブルAには、「日付」、「当者コード」 などの項目があります。 テーブルBの項目は「担当者コード」のみです。また、1レコードしか登録 されていません(2レコード以上になることはありません)。 そこで、テーブルAに対するデータ抽出条件を、テーブルBの「担当者」としたいのですが、 どのように記述すればよろしいでしょうか・・・? よろしくお願いします。

  • 重複に対しフラグをたてるたい

    EXCEL2000を使用しています。 *1つのIDコードに対し、レコード作成日が複数あります。 *レコード作成日の新しいIDコードにフラグをたてたい。 例) IDコード  作成日 フラグ 11111   1990/1/1 11111   2001/10/10  11111   2006/8/23  1 22222   1978/2/8 22222   1996/5/5  1 至急、ご回答のほど、よろしくお願いいたします。

  • 大量データの取得処理について

    テーブル1のレコードを全件取得し、取得したレコードの特定の項目を一件ずつチェックし、テーブル2の値を更新する処理を考えています。 しかし、テーブル1のレコード数が8万件存在するため、一気に全件を取得するのはまずいことになるのではと危惧しています。 そこで、fetch first ~ rows を使用するため、テーブル1に項目を追加し、更新が済んだらその項目にフラグを立てるような処理も考えましたが、 たった一度の処理のためにテーブルに項目を追加するのもどうかなと思っています。 1000件くらいずつ順番に取得できる良い方法があったら教えてください。 よろしくお願い致します。 ちなみにデータベースはDB2を使用しています。

  • Accessのクエリによる集計が出来ない

    Accessのクエリによる集計が出来ない kamuycikapです。 OKWaveで様々な方のアドバイスを頂きながら、慣れないAccessと悪戦苦闘しております。 一昨日、計算したい表を作成する為にOKWaveに質問を載せました。 http://okwave.jp/qa/q5549286.html 無事に上記のアドバイスでリレーションのオプション設定を行い、集計計算したいクエリの結果を表示することが出来ました。 その表を元にして 下記の質問でアドバイス頂いた方法による集計を行おうとしたのですが、集計出来なくて困っています。 http://okwave.jp/qa/q5544785.html データベースの構成とキーは以下のとおりです。 --ここから <データベース構造:リレーションシップ> リレーションシップとテーブルの構成は下記の通りです。 -->がリレーションシップです。 Kがキーになります。 ■テーブルA      ■テーブルB    ■テーブルC    ■テーブルD K納品書コード --> K納品書コード --> K納品書コード  --> K納品書コード 仕入数          K商品コード  --> K商品コード   --> K商品コード                             K商品連番    --> K商品連番                             出品数量        K出品連番                             商品名           発送個数                             色             発送日付                             サイズ                             売値 ※テーブルCからテーブルDへのリレーションオプションを「’テーブルC’の全レコードと’テーブルD’の同じ 結合フィールドのレコードだけを含める。」としています。 <作りたいデータ> 納品書コード、商品コード、商品連番、商品名、色、サイズ、売値、仕入数、出品数量、発送個数、出品在庫数、倉庫在庫 <クエリ> ○グループ  納品書コード、商品コード、商品連番、商品名、色、サイズ、売値、仕入数、出品数量 ○合計(集計)  発送個数 ○出品在庫数(演算)  [出品数量]-[発送個数] ○倉庫在庫(演算)  [仕入数]-[発送個数] <データ状況> テーブルCのデータは約300レコードありますが、そのうち20件ほどしか商品が発送されていない為、テーブルDのデータは20件しかありません。 <望む結果> テーブルCのデータが全て表示され、紐つけられたテーブルDのデータがが存在する場合は、発送個数を表示し出品在個数を演算する。 演算した出品在個数を利用して、倉庫在庫も演算する。 <クエリの実行結果> テーブルCのデータが全て表示され、テーブルDに紐つけられたレコードも表示されるが、テーブルDに入力されている20件のデータが商品連番(テーブルCのフィールド)ごとに集計されない。 --ここまで <目的> お店に出品された商品は、日を分けて少しずつ売れていきます。(一日で全部売れることもありますが....) 従って、出品された商品(テーブルCのデータ)に対して売れていく数(テーブルDの複数のレコード)のデータがぶら下がっている形になります。 このようなデータベースですので、出品した商品が何個売れたかを計算する為には、商品に対する売れた個数を集計(合計)しなければなりません。 <結果> テーブルCの商品連番ごとの発送個数を集計したいのですが、テーブルDの出品連番ごとの集計になっている様子です。 <頂きたいアドバイス> 上記のデータベースとクエリで、テーブルCの商品連番に紐ついたテーブルDに格納されている発送個数の合計値を集計するための方法 以上、識者の方のアドバイスをお願い致します。

  • Accessで、横長のテーブルを縦長に作り変えたい

    下のような項目の、「銀行休日マスタテーブル」が存在します。 1レコードの中に、 銀行、年、月をキーとして、1日~31日の休日・営業日の情報を格納しています。 (「1日」~「31日」の0と1は営業日と休日を表すフラグです。) 銀行コード| 年 |月|日数|1日|2日|・・・・30日|31日| 0001   |2006|01| 31|  1|  0|・・・・   1|   0| このテーブルを、以下のように、 銀行コード・年・月・日をキーとしたテーブルに作り変えたいのですが いいアイデアはあるでしょうか。 銀行コード| 年 |月|日|営業日フラグ| 0001   |2006|01| 1|      1| 0001   |2006|01| 2|      0| ・ ・ ・ 0001   |2006|01|30|      1| 0001   |2006|01|31|      0|