• ベストアンサー
  • すぐに回答を!

SQL構文を手助けしてください

(1)のようなテーブルデータを(2)のように表示したいと思います。 AA,BB,CC,DD,EEは列名としてください。 (1) AA BB CC DD EE __________________________ 00 01 2004/01/01 XX YY 01 00 2004/01/01 XE YD 01 00 2004/01/05 XZ YZ 02 01 2004/01/10 X2 YE 02 02 2004/01/05 XW YI 02 02 2004/01/06 XF YL (2) AA BB CC DD EE __________________________ 00 01 2004/01/01 XX YY 01 00 2004/01/05 XZ YZ 02 01 2004/01/10 X2 YE 02 02 2004/01/06 XF YL <条件> AAとBBでキーを作り、CCのMAXの該当レコードを表示したい。 SELECT AA,BB,MAX(CC),DD,EE FROM TEST_TABLE GROUP BY AA,BB というような感じかなと思ったのですが、「GROUP BY の式ではありません」と怒られてしまいます。 どなたか簡単なやり方をご存知で無いでしょうか?

共感・応援の気持ちを伝えよう!

  • 回答数2
  • 閲覧数94
  • ありがとう数13

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

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

 そのSELECT文、根本的に、条件に無理があります。条件が足りないというか・・・  たとえば、元テーブルの、AA,BB = 01,00 の所を例に取りましょう。該当するレコードは、2件あります。CCの最大値は、明確に定義されていますから、簡単です。2004/01/05です。  ところで、このとき、DD,EEは、いったい何になるんでしょうか?(2)のテーブルでは、XZ,YZとなっていますが、これはなぜですか?なぜ、XE,YDではないのですか?と、まぁこういう事をデータベースは問いかけています。  そう。DD,EEに対する条件が足りないんです。「GROUP BYの式ではありません。」と言うのは、そういう意味です。  基本的に、GROUP BYを指定した場合は、SELECTの列リストには、GROUP BYに列挙された式と集合関数しか書けません。文法的に言うとこうなります。  CCがMAXの列のDDとEEとなると、少々面倒です。  ここで、新しい条件として、AA,BB,CCの組みは、一意のキーを構成するという条件を付けます。でないと、一つのAA,BB,CCに対して、複数の列が該当すると言うことになり、さっきの話がぶり返しますので。  わかりやすい方法としては、VIEWを作っちゃうことでしょうか。 CREATE VIEW TEST_TABLE_M (AA,BB,CCM) AS SELECT AA,BB,MAX(CC) FROM TAST_TABLE GROUP BY AA,BB として、VIEWを定義し、このテーブルと結合します。 CREATE AA,BB,CCM,DD,EE FROM TEST_TABLE A, TEST_TABLE_M M WHERE A.AA=M.AA AND A.BB=M.BB AND A.CC=M.CCM といったところでしょうか。  VIEWを作りたくないのであれば、サブクエリーで条件を書くことになりますが、なんだか、条件が結構、長くなりそうです。「簡単な」とはいいがたくなります。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

回答ありがとうございます。 例題のSQLの矛盾は投稿した後に気付きました。 うん、DD,EE列になにを表示していいかわからないですもんね、、、 VIEWを使えばわかりやすくなりますね。 まぁ結果的に言えばそれほど簡単ではないですね(^^;) どうもありがとうございました

関連するQ&A

その他の回答 (1)

  • 回答No.2

下記SQL文は一応動作確認しました。そのまま、エラー無しで使用できると思います。 但し、テーブルの列定義は create table TEST_TABLE ( AA char(2), BB char(2), CC date, DD char(2), EE char(2) ); と仮定しています。列の型が違う場合、文字列処理部分を修正して下さい。 サブクエリーを使用しないシンプルなSQL文を紹介します。ですので、 レスポンスは早いと思います。 (但し、列DD, EEの列長があまりにも長い場合は、レスポンスが遅くなるかも しれませんので、その場合は、#1さんの方法や、サブクエリーを使った方法を 試してください。そうでなければ、このSQL文で大丈夫です。) (SQL1) SELECT AA, BB, MAX ( to_char( CC, 'yyyy/mm/dd' ) || '*' || DD || '*' || EE ) FROM TEST_TABLE GROUP BY AA,BB; MAX()で、同一キーの、列CC, DD, EE を文字連結した文字列の最大値を返します。 日付形である列CCを連結文字の先頭に配置しているため、直近の日付のレコードの CC, DD, EE を取得できます。 '*' は一応デメリッタです。 プログラム側で、3つ目の列(MAXの列)の値を分解し、それぞれの列の値(CC, DD, EE)を 取得します。 (SQL2) プログラム側で3つ目の列(MAXの列)の文字列分解処理を行いたくない場合、 SQL1をFROM句のサブクエリーとすることで、文字列分解処理をSQL文側で 行うことも可能です。この場合のサブクエリーはレスポンスに殆ど悪影響を 及ぼしません。 下記では、列DD, EEの値は固定長と仮定していますが、可変長の場合は、 INSTR()でデミリタ '*'を検索し、切り取る位置を動的に処理することも可能です。 また、プログラムから使用することも考慮し、列名 CC, DD, EE も別名をつけて、 アクセスできるようにしています。 select AA, BB, to_date ( substr( max_row, 1, 10 ), 'yyyy/mm/dd' ) CC, substr( max_row, 12, 2 ) DD, substr( max_row, 15, 2 ) EE from ( SELECT AA, BB, MAX ( to_char( CC, 'yyyy/mm/dd' ) || '*' || DD || '*' || EE ) max_row FROM TEST_TABLE GROUP BY AA,BB);

共感・感謝の気持ちを伝えよう!

質問者からのお礼

デリミタの使用ですか。これまた考えていませんでした。 というか今までそういう考えをしたことがありませんでした。これからも役立ちそうなことを教えていただけたと思います。 また、MAXの中でMAX ( to_char( CC, 'yyyy/mm/dd' ) || '*' || DD || '*' || EE ) という使い方も出来るというのは知りませんでした。 ちょっとビックリしました。 お二方のご助言でなんとかなりそうです ありがとうございました!

関連するQ&A

  • Accessで2つのカラムからユニークに抽出

    inusrとoutusrからメールアドレスの一覧として aa@aa.com bb@bb.com cc@cc.com dd@dd.com ee@ee.com が取得できるようにするためのSQLを教えてください。 select b,c from inusr left join outusr on b=c ? に似たようなSQLになると思います。 テーブルは以下のようなものです。 できれば上に書きましたSQLのようにbとcに分かれてしまうのではなく 1つの変数で結果を取得したいです。 inusr a b 1 aa@aa.com 2 bb@bb.com 3 aa@aa.com 4 dd@dd.com 5 ee@ee.com outusr a c 1 cc@cc.com 2 bb@bb.com 3 ee@ee.com 4 aa@aa.com 5 ee@ee.com

  • Oracle SQLでのデータ抽出

    Oracle、SQLともに初心者のため困っています。 どなたか教えてください。 フィールド1、2で重複(2件以上存在)するレコードに対して、そのテーブルの全項目を取得したいのです。 例: 処理前 フィールド1,フィールド2 ,フィールド3 1 , AA, 1 1 , AA, 2 1 , BB, 3 1 , BB, 4 2 , CC, 5 2 , CC, 6 3 , DD, 7 4 , EE, 8 5 , FF, 9 処理後 フィールド1, フィールド2,フィールド3 1 , AA, 1 1 , AA, 2 1 , BB, 3 1 , BB, 4 2 , CC, 5 2 , CC, 6 どうしたらよいでしょうか? よろしくお願い致します。

  • Excel2003で他の列のデータをドロップダウンリストに

    質問のし直しです。 下記の場合、B列でのドロップダウンリストに(aa bb cc dd ee)と表示させるには、どうしたら良いのでしょうか? A列  B列 bb     dd aa     ee bb     ee cc    dd aa bb 実際には文字列なのですが、1300行で、A列のデータは300個位在ります。 宜しくお願い致します。

  • Google Chromeの同期について

    パソコンを2台使っていて、両方とも全く同じブックマークだった場合に同期をしたらブックマークは重複してしまうのでしょうか? PC1:A,B,C,D,E PC2:A,B,C,D,E を同期したら PC1:AA,BB,CC,DD,EE PC2:AA,BB,CC,DD,EE となりますか?

  • 深い要素の取り出し方

    下のような場合、一般的にはforeachを使うと思いますが、 $sample[cc]->[0]->[xx]の要素である「さ」だけを取り出す場合はどのようにしたら取り出せるのでしょうか? $sample [aa] => あ [bb] => か [cc] => Array   (    [0] => Array     (      [xx] => さ      [yy] => た     )    [1] => Array     (      [xx] => な      [yy] => は     )   )

    • ベストアンサー
    • PHP
  • エクセルの集計計算について教えてください

    期間を指定するとデータを引っ張ってきます データは1000&#65374;2000件程存在します Aセル=名前 Bセル=略号 Cセル=日時 Dセル=場所 Eセル=不良合計 名前    略号       日時            場所    不良合計 A0001     AA   2014/06/01 00:04:28   1     7 A0010     BB   2014/06/01 00:18:10   2     3 A0011     DD   2014/06/01 00:29:35   4     8 A0001     EE   2014/06/01 00:24:55   2     9 A0005     CC   2014/06/01 00:29:35   3     4 A0010     BB   2014/06/01 00:27:09   2     6 A0020     AA   2014/06/01 00:32:13   1     4 A0001     AA   2014/06/01 00:33:26   3   3 A0020     EE   2014/06/01 00:37:31   5  17 A0016     FF   2014/06/01 00:47:22   6   7 A0030     BB   2014/06/01 00:54:35   2   3 A0015     AA   2014/06/01 01:01:11   1   2 A0001     DD   2014/06/01 01:03:01   4   8 A0020     EE   2014/06/01 01:06:21   5   11 A0011     BB   2014/06/01 01:08:19   2   4 A0005     DD   2014/06/01 01:17:20   4     13 A0011     BB   2014/06/01 01:22:41   2   8 A0016     AA   2014/06/01 01:23:47   1   2 A0010     CC   2014/06/01 01:25:08   3   11 .... 名前が同じ物でも、場所が異なると略号が変わってしまいます。 流れとしてはA001の物が場所1→2→3と進んで行きます。    名前   略号         日時         場所      不良合計 A0001   AA   2014/06/01 00:04:28   1   2 A0001   BB   2014/06/01 01:04:28   2   4 A0001   CC   2014/06/01 02:04:28   3   8 A0001   DD   2014/06/01 03:04:28   4   10 不良合計に関しては、前の物が加算されていく形になっています。 数千あるこのようなデータを今手計算で、場所毎の不良数を求めています。 例を挙げますと、上の4つのデータの場合 DDの不良合計とCCの不良合計を引いて、DDの不良合計は2 CCの不良合計とBBの不良合計を引いて、CCの不良合計は4 BBの不良合計とAAの不良合計を引いて、BBの不良合計は2 A0001   AA   2014/06/01 00:04:28   1   2 A0001   BB   2014/06/01 01:04:28   2   2 A0001   CC   2014/06/01 02:04:28   3   4 A0001   DD   2014/06/01 03:04:28   4   2 と言う形に手計算で置き換えてします。 ただ、数が膨大であり、名前に関しても同じ名前が1つではなく複数使われている事もあり計算が大変です。 何とか楽に計算する方法はないでしょうか? VBA?を使用してでもいいので、短時間で出来る集計方法があれば教えてください。

  • DBI、joinsした時の、出力構造について

    先日、 joinした際、同じidのものは 纏まってくれたらハッピーだと考えました。 あれそれ動かしてきたのですが、出力結果でゴニョゴニョ行うのではなく、 一発で 目的の出力結果にならないものでしょうか。 よろしくお願いします。 テーブル1 a___b___c_ 1___BB__CC 2___BB__CC 3___BB__CC テーブル2 d___e___f D___E___1 D___E___2 D___E___2 結合テーブル a___b___c___d___e___f 1___BB__CC__DD__EE__1 2___BB__CC__DD__EE__2 2___BB__CC__DD__EE__2 3___BB__CC__ 出力結果 $VAR1_=_[ __________{ ____________'a'_=>_1, ____________'b'_=>_BB, ____________'c'_=>_CC, ____________'d'_=>_DD, ____________'e'_=>_EE, ____________'f'_=>_1, __________}, ____________[ ______________{ ________________'a'_=>_2, ________________'b'_=>_BB, ________________'c'_=>_CC, ________________'d'_=>_DD, ________________'e'_=>_EE, ________________'f'_=>_2, ______________}, ______________{ ________________'a'_=>_2, ________________'b'_=>_BB, ________________'c'_=>_CC, ________________'d'_=>_DD, ________________'e'_=>_EE, ________________'f'_=>_2, ______________}, ____________] __________,{ ____________'a'_=>_1, ____________'b'_=>_BB, ____________'c'_=>_CC, ____________'d'_=>_, ____________'e'_=>_, ____________'f'_=>_, ___________}, よろしくお願いします。

    • ベストアンサー
    • Perl
  • エクセルで重複行をすべて削除するにはどうすればよいでしょうか?

    例えば、昇順で並べ替えて以下のようにエクセルで準備したとします。   A列 1行 aa 2行 aa 3行 bb 4行 bb 5行 cc 6行 cc 7行 dd 8行 ee そこで重複する行ごと削除したいのですがどうすればよいでしょうか? 削除結果は   A列 1行 dd 2行 ee 上記のようにしたいです。 重複する1行だけは削除できたのですが、 2行ごと削除の方法がわかりません。 ご教授いただきたく存じます。 よろしくお願いいたします。

  • エクセルのセル分けについて教えてください。

    エクセルで、1つのセルに  aa,"bb","cc,"dd","ee" というように入力されています。 それをaa bb cc のようにそれぞれのセルに分けたいのですが、方法が分かりません。 ご存知の方がいらっしゃいましたら、教えてください。宜しくお願いします。

  • ASPによるSQL構文で2つのデータベースを連結

    下記のように2つのデータベースを連結させたいのですが うまくいきません。 仕事で緊急なのでわかる方教えてください。 データベースはACCESSです。 テーブル1 A | B(日付) ---|---------- aa |2004/01/01 bb |2004/02/02 テーブル2 C | D(日付) ---|---------- cc |2004/03/03 dd |2004/04/04 ee |2004/05/05 結果 A | BD(日付) | C ---|----------|---- aa |2004/01/01| bb |2004/02/02|   |2004/03/03| cc   |2004/04/04| dd   |2004/05/05| ee strSQL="SELECT A,B,null FROM テーブル1 union all SELECT null,D,C FROM テーブル2" Set RgRs = cnn.Execute(strSQL) 上記の記述で結合させても、うまくいきませんでした。 宜しくお願いします。