2016-04-21 117 views
2

我使用INSERT IGNORE插入所有三列唯一的数据。如何排除时间并检查日期是否与下面两列相同?INSERT IGNORE for date,忽略时间

唯一索引列:时间戳,作用,价值

时间戳格式: 2016年4月21日十三时33分47秒

我的表样:

2016-04-21 13:33:47,发送,邮箱

2016-04-20 11:21:32,发送,邮箱

2016年4月19日17:32:65,发送电子邮件

我想要做的事: 如果我尝试插入下面的数据,应该被忽略,因为有对现有数据2016-04-21,发送,邮件。

2016年4月21日19时33分47秒,发送电子邮件

+0

顺便说一句,2016-04-19 17:32:65不是一个有效的时间戳。我假设秒是一个错字。 –

回答

1

IGNORE将工作的唯一方法是,如果你有一个UNIQUE指数一列或多列。在这种情况下,您需要一个来自DATETIMEDATE字段。

例如:

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或更高版本,您可以创建一个具有唯一索引的生成列。

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

随着MySQL的早期版本,你需要添加一列来存储日期和使用触发器(可从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 Syntax](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

的数据,如果在子查询的条件不具备任何的比赛将只进行插入。