アプリ版:「スタンプのみでお礼する」機能のリリースについて

TableName = key_table
ID, GroupID, Key(文字列型), Value(文字列型)
1, 1, 'start_date', '2014-11-05'
2, 1, 'end_date', ''
3, 2, 'start_date', '2014-11-05'
4, 2, 'end_date', '2014-12-05'
5, 3, 'start_date', '2014-4-05'
6, 3, 'end_date', ''

start_dateが2014-11-05で、end_dateが''か未来にセットされているGroupID1とGroupID2を検索するSQLはどういう方法がありますでしょうか?
SELECT GroupID from key_table where (Name='start_date' AND Value = '2014-11-05') AND (Name='end_date' AND (Value = '' OR end_date > '2014-11-05')
な感じでやってみようと思ったのですが、動作しません。
このテーブル構造でどうしても検索しないといけません。

以上、よろしくお願いします。

A 回答 (2件)

self joinで無理矢理、table構造を作り替えるとか?



select st.GroupID
from ( select * from `key_table` where key='start_date' and Value = '2014-11-05' ) as st
inner join ( select * from `key_table` where key='end_date' and (Value > curdate() or Value="") ) as en
on st.GroupID = en.GroupID ;

大量行数になると、No1の方の回答のほうが速度は速いと思われる。
GroupID と Key カラムで連動unique index が貼ってある前提も必要。
GroupID が同じ行は必ず2行なのでしょうか?start_date の行はあるけど、end_date の行が無い場合は、選ばなくてもよいなら上記でok
end_dateの行が未入力で start_date がマッチするものもほしいなら、left join して以下のように

select st.GroupID
from ( select * from `key_table` where key='start_date' ) as st
left join ( select * from `key_table` where key='end_date' ) as en
on st.GroupID = en.GroupID
where st.Value = curdate() and (en.Value > curdate() or en.Value="" or en.Value is null )
;

蛇足:日付文字列のカラムは、date 型にしておいたほうが、エラー日付を弾いたり、日数計算に日付処理関数が使えるので便利ですよ。
    • good
    • 0

構造が悪いのはしょうがないとして


こんな感じ?

select GroupID
from key_table
where (`Name`='start_date' and `Value`='2014-11-05')
or (`Name`='end_date' and (`Value`='' or Value > now()))
group by GroupID
having count(*)=2
    • good
    • 0

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