Reputation: 131
I'm inserting data that are unique for all three columns using INSERT IGNORE. How can I exclude the time and check the date if its unique with the other two columns below?
Unique index for columns: timestamp, action, value
Time stamp format: 2016-04-21 13:33:47
My table sample:
2016-04-21 13:33:47, send, email
2016-04-20 11:21:32, send, email
2016-04-19 17:32:65, send, email
What I'm trying to do: If I try to insert the data below, it should be ignored because there's existing data for 2016-04-21, send, email.
2016-04-21 19:33:47, send, email
Upvotes: 2
Views: 1259
Reputation: 31812
You can use an INSERT SELECT statement with constant data from a dummy table. This way you can include a WHERE clause.
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
The data will only be inserted if the condition in the subquery does not have any matches.
Upvotes: 1
Reputation: 4218
If you are using MySQL 5.7.6 or higher, you can create a generated column with a unique index.
ALTER TABLE table_name
ADD COLUMN timestamp_date DATE GENERATED ALWAYS AS (DATE(timestamp)) STORED,
ADD UNIQUE (timestamp_date, action, value);
With an earlier version of MySQL, you'll need to add a column to store the date and use a trigger (available from version 5.0.2) to update it whenever you insert new records in the table.
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'
Upvotes: 1
Reputation: 211610
The only way an IGNORE
will work is if you have one or more columns in a UNIQUE
index. In this case you need a DATE
field that's derived from your DATETIME
.
For example:
ALTER TABLE my_emails ADD COLUMN sent_date DATE
CREATE UNIQUE INDEX idx_sent_date ON my_emails (sent_date)
Then you can populate it:
UPDATE my_emails SET sent_date=DATE(sent_datetime)
With whatever those columns are. From that point forward you'll need to be sure you populate both fields.
Upvotes: 1