2008-07-29
SQL 期間の重複をチェック
EC-CUBEにはキャンペーン機能があります。カスタマイズ要件として、新規登録時に既存のキャンペーンとは期間がかぶらないようにしたい、というものがありました。
dtb_campaign
| campaign_id | point_rate | start_date | end_date | del_flg |
|---|---|---|---|---|
| 1 | 5 | 2008-07-01 | 2008-08-31 | 0 |
テーブルを簡略化したものが上記です。このようなデータがある場合だと、7/1以前に期間が終了するか、8/31以降に期間が開始されるキャンペーンだけが登録できればいいことになります。
フォームから受け取って、さらにDB用に整形した値を以下とします(PHPです)。
- $start_date…キャンペーン開始日時
- $end_date…キャンペーン終了日時
SQLは、重複するデータの有無をカウントをとって調べるものとします。最初に考え付いたのがこちら↓。
SELECT COUNT(campaign_id) FROM dtb_campaign WHERE ((start_date BETWEEN $start_date AND $end_date) OR (end_date BETWEEN $start_date AND $end_date) OR (start_date <= $start_date AND end_date >= $end_date)) AND del_flg = 0
これは…明らかにスマートではないですね。実は最初は4行目は無くて、それだと例えば「7/15〜8/15」とかをスルーされてしまうのに気づき、無理やり追加したというかたちです。
で、時間をおいて考えてみた改良版がこちら↓。
SELECT COUNT(campaign_id) FROM dtb_campaign WHERE (($start_date BETWEEN start_date AND end_date) OR ($end_date BETWEEN start_date AND end_date)) AND del_flg = 0
発想の転換をして、BETWEENの期間のほうにテーブルのフィールドを持ってきてみました。最初のSQLよりもスッキリしていますし、結果は正しく取れるはずです。はず、というのは、まだ試してないからです*1。 →追記へ
ちなみに、既存のキャンペーンを編集→更新する際の重複チェックは、キーとなる$campaign_idがセットされているかどうかで判断し、WHERE句に「AND campaign_id <> $campaign_id」を追加するようにすればいいと思います。
【追記】
すいませんできませんでした。「6/1〜9/1」のように期間を覆う場合をスルーしてしまいました。さらに改良したのがこちら↓。
SELECT COUNT(campaign_id) FROM dtb_campaign WHERE (start_date <= $end_date AND end_date >= $start_date) AND del_flg = 0
実際に試したのでできている(はず)です。詳しくは次の記事を予定。
*1:明日試します
トラックバック - http://d.hatena.ne.jp/deeeki/20080729/termchecksql
リンク元
- 118 http://www.google.co.jp/search?hl=ja&source=hp&q=SQL+期間重複&lr=&aq=f&oq=
- 68 http://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=UTF-8&rlz=1T4SUNA_jaJP285JP285&q=SQL+期間重複
- 44 http://www.google.co.jp/url?sa=t&rct=j&q=sql 期間 重なり&source=web&cd=1&ved=0CBsQFjAA&url=http://d.hatena.ne.jp/deeeki/20080729/termchecksql&ei=HRSETrr_I8TmiALsl42oDA&usg=AFQjCNFx9dZsGrCSQg2SEOjXVS
- 41 http://www.google.co.jp/search?hl=ja&q=SQL+期間 重複&lr=
- 38 http://www.google.co.jp/url?sa=t&source=web&cd=1&ved=0CBkQFjAA&url=http://d.hatena.ne.jp/deeeki/20080729/termchecksql&rct=j&q=sql 期間 重複&ei=M9rDTdKdEoaevQPvx8SVAQ&usg=AFQjCNFx9dZsGrCSQg2SEOjXVSwCGlwrzA
- 37 http://www.google.co.jp/search?hl=ja&source=hp&q=期間重複チェック&btnG=Google+検索&lr=&aq=f&oq=
- 34 http://www.google.co.jp/search?hl=ja&q=sql+??????+?????с?????&lr=&aq=f&oq=
- 34 http://www.google.co.jp/url?sa=t&rct=j&q=sql+期間+重複&source=web&cd=1&ved=0CCkQFjAA&url=http://d.hatena.ne.jp/deeeki/20080729/termchecksql&ei=KxzOTsjYJYbbmAXi7IGlDQ&usg=AFQjCNFx9dZsGrCSQg2SEOjXVSwCGlwrzA
- 28 http://www.google.co.jp/search?hl=ja&client=firefox-a&rls=org.mozilla:ja:official&hs=exj&q=SQL+重複チェック&btnG=検索&lr=lang_ja
- 27 http://www.google.co.jp/search?q=SQL+期間+重複&lr=lang_ja&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:ja:official&client=firefox-a



