プロが教えるわが家の防犯対策術!

MySQLで(Javaで)、
1.過去のみに、予約日のあるユーザーのレコードの最大日時のレコードを抽出
2.指定日以降に、予約日があれば、そのユーザーのレコードは、抽出しない。
SQL文を教えてください。


SQLへ、 検索キー: name like '%山田%' と、yoyaku_date = '2015-12-03' を指定した場合、
下記のレコードのみちゅしゅつしたい。


データ例)

id user_id sei mei yoyaku_date yoyaku_time sakujyo
※ sakujyo=1は、論理削除で抽出対象外。
-------------------------------------------------------------------------
1 30 山田 浩司 2015-12-02 09:00 0
2 30 山田 浩司 2015-10-30 18:21 0
3 30 山田 浩司 2015-12-02 11:00 0 ← 抽出対象
4 30 山田 浩司 2015-12-02 10:00 1

5 40 鈴木 孝雄 2014-12-03 18:40 0 ← 指定日以降があるので、
6 40 鈴木 孝雄 2015-12-03 09:00 1 user_id=40のこれーどは、
7 40 鈴木 孝雄 2015-12-02 11:00 0 抽出対象外。
8 40 鈴木 孝雄 2015-12-02 10:00 1
-------------------------------------------------------------------------

A 回答 (1件)

誰かいい方法を思いつく人がいないかと思って、様子を見ていたのですが、誰も回答しないようなので、回答しておきます。



いくつかめんどくさい問題があります。
それは主に「name like '%山田%' 」という検索キーが問題になります。
(name ではなく sei だと思いますが)

この条件では、
山田浩司さん以外にも山田さんがいた場合、
姓に山田を含む「前山田」さんなどがいた場合、
など、複数の人が検索される可能性があります。

その場合、一つのSQL文で、それぞれの人についての過去の最新のレコードを検索するとなると、かなりメンドクサイSQLになってしまいます。

また、場合によっては、user_idが同じでも結婚などによって途中で姓が変わった人のことも考慮する必要があるかもしれません。

そのため「sei like '%山田%' 」はやめて「user_id = 30」でいいことにすれば、

SELECT * FROM テーブル名 t WHERE (user_id = 30) AND (yoyaku_date < '2015-12-03') AND (sakujyo != 1) AND (NOT EXISTS (SELECT * FROM テーブル名 e WHERE (e.id = t.id) AND (e.yoyaku_date >= '2015-12-03') AND (e.sakujyo != 1))) ORDER BY yoyaku_date DESC, yoyaku_time DESC LIMIT 1;

で、idが3のレコードが検索されます。


念のために解説しておくと、

NOT EXISTS (SELECT * FROM テーブル名 e WHERE (e.id = t.id) AND (e.yoyaku_date >= '2015-12-03') AND (e.sakujyo != 1))
は、「指定日以降に、予約日があれば、そのユーザーのレコードは、抽出しない。」の指定です。

ORDER BY yoyaku_date DESC, yoyaku_time DESC LIMIT 1
は、新しい順に並べて最初の1つを検索する指定です。
    • good
    • 0

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