2016-04-21 6 views
2

INSERT IGNOREを使用して3つの列すべてに固有のデータを挿入しています。下の他の2つの列と一意の場合は、時間を除外して日付を確認するにはどうすればよいですか?時間を無視して日付のINSERT IGNORE

列のためのユニークなインデックス:タイムスタンプ、行動、価値

タイム・スタンプ・フォーマット: 2016年4月21日13時33分47秒

私のテーブルのサンプル:

2016-04-21 13:33:47、send、email

2016-04-20 11:21:32、send、email

2016年4月19日17:32:65、私は何をしようとしている、電子メール

を送信:私は、以下のデータを挿入しようとした場合のために既存のデータがありますので 、それは無視されるべきです2016-04-21、send、email。

2016年4月21日19時33分47秒、送信、電子メール

+0

ところで、2016-04-19 17:32:65は有効なタイムスタンプではありません。私は秒がタイプミスであると仮定しています。 –

答えて

1

あなたはUNIQUEインデックス内の1つ以上の列を持っている場合IGNOREが動作する唯一の方法です。この場合、DATETIMEから派生したDATEフィールドが必要です。例えば

ALTER TABLE my_emails ADD COLUMN sent_date DATE 
CREATE UNIQUE INDEX idx_sent_date ON my_emails (sent_date) 

その後、あなたはそれを移入することができます

UPDATE my_emails SET sent_date=DATE(sent_datetime) 

それらの列があるものは何でもして。その時点から、両方のフィールドを確実に入力する必要があります。

1

MySQL 5.7.6以降を使用している場合は、固有のインデックスを持つ生成カラムを作成できます。 MySQLの以前のバージョンで

ALTER TABLE table_name 
ADD COLUMN timestamp_date DATE GENERATED ALWAYS AS (DATE(timestamp)) STORED, 
ADD UNIQUE (timestamp_date, action, value); 

は、日付を保存して、テーブルに新しいレコードを挿入するたびに、それを更新するために、(バージョン5.0.2から入手可能)のトリガを使用する列を追加する必要があります。

ALTER TABLE table_name 
ADD COLUMN timestamp_date DATE; 

CREATE TRIGGER insert_table_name_date BEFORE INSERT ON table_name 
FOR EACH ROW SET NEW.timestamp_date = DATE(NEW.timestamp); 

-- If you already have any data in the table, update it to add the date. 
UPDATE table_name SET timestamp_date = DATE(timestamp_date); 

ALTER TABLE table_name 
ADD UNIQUE (timestamp_date, action, value); 

INSERT INTO table_name(timestamp, action, value) VALUES 
('2016-04-21 13:33:47', 'send', 'email'), 
('2016-04-20 11:21:32', 'send', 'email'), 
('2016-04-19 17:32:55', 'send', 'email'); 

-- 3 row(s) affected 

INSERT INTO table_name(timestamp, action, value) VALUES 
('2016-04-21 19:33:47', 'send', 'email'); 

-- Error Code: 1062. Duplicate entry '2016-04-21-send-email' for key 'timestamp_date' 
+0

インデックスを作成するには、5.7.8が必要です。「MySQL 5.7.8より前では、仮想カラムをインデックスできません。MySQL 5.7.8以降、InnoDBは仮想カラムのセカンダリインデックスをサポートしています。 [CREATE TABLE構文](http://dev.mysql.com/doc/refman/5.7/en/create-table。html) –

+0

@Paul Spiegel私はテストできません、私は5.7.6持っていません。しかし、私の理解では、**仮想**生成列はインデックスに登録することはできませんが、**生成列は**保存することができます。 –

+0

あなたは正しいです:「格納された列には記憶領域が必要でインデックスに登録することができます。しかし、 - 良い解決策。 –

1

あなたはダミーのテーブルから定数データとINSERT SELECTステートメントを使用することができます。この方法で、WHERE句を含めることができます。

insert into actions (`timestamp`, action, value) 
    select '2016-04-21 19:33:47', 'send', 'email' 
    from (select 1) dummy 
    where not exists (
     select 1 
     from actions 
     where action = 'send' 
      and value = 'email' 
      and date(`timestamp`) = '2016-04-21' 
    ); 

http://sqlfiddle.com/#!9/5882c/1

サブクエリの条件がすべての試合を持っていない場合のみデータが挿入されます。

関連する問題