🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Q&A

解決済

4回答

1806閲覧

プロモーションコードを期間内においてユニークにするには

m0a

総合スコア708

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

0グッド

0クリップ

投稿2019/12/03 07:32

プロモーションコードを管理するテーブルを作成しています

CREATE TABLE promotion_codes( id SERIAL PRIMARY KEY, code VARCHAR(25) NOT NULL, start_at TIMESTAMP WITH TIME ZONE NOT NULL, expired_at TIMESTAMP WITH TIME ZONE NOT NULL, );

promotion_codes.codeがプロモーションコード本体で有効期間がstart_at〜expired_atを想定しています。

ここで、codeに対してUNIQUE制約をつけたいのですが、start_at〜expired_atの期間内においてUNIQUEにするという制約は可能なものでしょうか?CHECK制約で制限可能であればご教示ください。

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2019/12/03 07:36

わざわざ中途半端な制約をかけるより、「全期間を通してUNIQUE」のほうが管理しやすいかと思いますが、そうできない理由はありますでしょうか。
m0a

2019/12/03 07:42

例えば株主番号など、決められた文字列をプロモーションコードとして用いなくてはいけない場合があります。その場合毎年同じ文字列を使うことになるのでUNIQUE制約に対して期限を設けたいのです。
Y.H.

2019/12/03 08:08

> start_at〜expired_atの期間内においてUNIQUE 期間は重なることはあるのでしょうか? 1. 2019/07/01~2019/07/31 2. 2019/07/15~2019/08/15 のような場合、2019/07/15~2019/07/31 の期間は、1,2を通してユニークであるとか。
guest

回答4

0

ベストアンサー

条件は
・start~end がかぶる期間において、同一のプロモーションコードがあってはならない
ですか?

制約でどうこうではなくてトリガで制御した方がよいような気がします。
before insert も before update も使えるはずですから、その中で

  • 登録しようとしているプロモーションコードと同一で、
  • 登録しようとしている start が start ~ end とかぶるか、end が start ~ end とかぶる

ならば登録失敗。

更新の場合は「更新しようとしている自分自身を除く」必要がありますが、これは「かぶる件数をカウントし、それが 2 より大きいなら失敗」(登録の場合は 1 より大きいと失敗)とすればほぼほぼ同一処理で済むでしょうか。

投稿2019/12/03 08:54

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m0a

2019/12/04 08:00

ありがとうございました。結局無理のある設計だと思い通常のUNIQUE属性ですすめることにしました。
guest

0

別のカラムで「ABCDEF20191203」みたいに、プロモーションコードと日付をくっつけたデータを持っておいて、そのカラムをUNIQUEにするとかどうでしょう。

投稿2019/12/03 07:54

Takumiboo

総合スコア2536

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

詳細条件が分かりませんが、5.3.3 一意性制約 で、複数列を指定することで、制約することもできそうですね。

投稿2019/12/03 08:31

CHERRY

総合スコア25218

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

コードは書きませんが、コードのテーブルを

|コード|タイムスタンプ|

のカラムに設定しておいて、このタイムスタンプでif文で論理演算をしないといけないと思います。
ミリ秒をタイムスタンプにとって重複しないようにコードを発行すればいいと思います。

投稿2019/12/03 07:56

kazukichi_0914

総合スコア25

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問