プロが教える店舗&オフィスのセキュリティ対策術

以下の(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の範囲で絞り込むため、別テーブルを作って、、、等の処理は避けたいのです。

最適な方法がございましたら、なにとぞご教示願います。

A 回答 (3件)

今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
;
    • good
    • 1
この回答へのお礼

下のSQL文が、まさに想像していた形です!
なるほど、このように書くのですね。
大変勉強になりました。

上のSQL文は、結果が少々違いました。
NOT EXISTSに関して自分が全く無知なので、これから調べてみます。

お礼が遅くなってすみません。
本当にありがとうございました!

お礼日時:2009/01/29 17:56

これでよいのでは?



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
    • good
    • 1
この回答へのお礼

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

大変勉強になりました。
本当にありがとうございました!

お礼日時:2009/01/29 18:00

RDBMSは、ここのカテゴリ通りMySQLですか?


バージョンは?

MySQL 4.0以前・・・一部のジョイン、union、一時表などは実装済
MySQL 4.1・・・ジョインの拡張、サブクエリ、unicodeなどの実装
MySQL 5.0・・・ビュー、ストアドプロシジャ、トリガなどの実装

バージョンにより、実装方法が異なってきます。

この回答への補足

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

補足日時:2009/01/27 10:23
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!