• ベストアンサー

SQL内でループさせるような検索文

以下の(1)のようなデータがあった場合、一つのSQL文で(3)の表が 取得できる方法はございますでしょうか? (1)table T_SAMPLE | UID | FLAG | CREATE_DATE | ------------------------------------------------ | 000 | A | 2009-01-26 00:00:00 |★ | 000 | A | 2009-01-26 00:00:10 | | 000 | B | 2009-01-26 00:00:20 | | 002 | A | 2009-01-26 00:00:05 |★ | 002 | B | 2009-01-26 00:00:13 | | 002 | A | 2009-01-26 00:01:00 | | 002 | B | 2009-01-26 00:02:02 | | 003 | B | 2009-01-26 00:05:00 |★ | 004 | B | 2009-01-26 00:00:00 |★ | 004 | B | 2009-01-26 00:00:15 | | 004 | A | 2009-01-26 01:00:00 | | 005 | B | 2009-01-26 00:00:11 |★ | 005 | B | 2009-01-26 00:04:05 | (2)同じUIDがあった場合、CREATE_DATEが早い情報(上表★)を使用 | UID | FLAG | CREATE_DATE | --------------------------------------------------- | 000 | A | 2009-01-26 00:00:00 |★ | 002 | A | 2009-01-26 00:00:05 |★ | 003 | B | 2009-01-26 00:05:00 |★ | 004 | B | 2009-01-26 00:00:00 |★ | 005 | B | 2009-01-26 00:00:11 |★ (3)FLAGでカウント <= 取得したい結果 | COUNT(FLAG) | FLAG | -------------------------------- | 2 | A | | 3 | B | イメージとしては、 [処理a] select FLAG from T_SAMPLE where UID = '000' order by CREATE_DATE limit 0,1 ×それぞれUID とすると、上記(1)→(2)で select UID,[処理aの結果においてUIDに対応したFLAG] from T_SAMPLE group by UID という状態の結果が一度のSQLで取得できればよいと考えているのですが。 実際にこの処理を実施する際は、自由に指定されるCREATE_DATEの範囲で絞り込むため、別テーブルを作って、、、等の処理は避けたいのです。 最適な方法がございましたら、なにとぞご教示願います。

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

  • ベストアンサー
  • bleis
  • ベストアンサー率68% (11/16)
回答No.2

今MySQLの環境がないのでSQL Serverでしか試してませんが、これでどうでしょう? 4.1でサブクエリが実装されてるということなので、動くと思うのですが・・・ SELECT   COUNT(*)  , flag FROM   T_Sample A WHERE   NOT EXISTS(    SELECT * FROM T_Sample B    WHERE A.uid = B.uid AND       B.create_date < A.create_date   ) GROUP BY   flag ; SELECT   COUNT(*)  , flag FROM   T_Sample A WHERE   A.create_date =    (SELECT MIN(B.create_date) FROM T_Sample B     WHERE A.uid = B.uid) GROUP BY   flag ;

noname#192489
質問者

お礼

下のSQL文が、まさに想像していた形です! なるほど、このように書くのですね。 大変勉強になりました。 上のSQL文は、結果が少々違いました。 NOT EXISTSに関して自分が全く無知なので、これから調べてみます。 お礼が遅くなってすみません。 本当にありがとうございました!

その他の回答 (2)

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.3

これでよいのでは? SELECT COUNT(FLAG) AS COUNT , FLAG FROM T_SAMPLE INNER JOIN ( SELECT UID,MIN(CREATE_DATE) AS CREATE_DATE FROM T_SAMPLE GROUP BY UID ) AS T2 ON T_SAMPLE.UID=T2.UID AND T_SAMPLE.CREATE_DATE=T2.CREATE_DATE GROUP BY FLAG

noname#192489
質問者

お礼

本当だ、このようにしても得られますね! 気づきませんでした。 つくづくSQLってパズルみたいだなって思います。 もっと柔軟な思考が大切ですね。 大変勉強になりました。 本当にありがとうございました!

回答No.1

RDBMSは、ここのカテゴリ通りMySQLですか? バージョンは? MySQL 4.0以前・・・一部のジョイン、union、一時表などは実装済 MySQL 4.1・・・ジョインの拡張、サブクエリ、unicodeなどの実装 MySQL 5.0・・・ビュー、ストアドプロシジャ、トリガなどの実装 バージョンにより、実装方法が異なってきます。

noname#192489
質問者

補足

MySQL 4.1となります。 よろしくお願いします。

関連するQ&A