Can you insert ignore into table if certain fields are duplicate? - mysql

I am trying to insert into a MySQL table, but I came across a problem that I can't seem to solve. The problem is that I want to add a record into the table if certain fields are duplicate, but not all.
To make my problem more clear this is the table:
When I want to do an insert into this table, I want to insert ignore only if userid and status and url are duplicate. If one of those 3 are unique the record can be added into the table.
What I have tried:
INSERT IGNORE INTO mydb.mytable (unique_screen_id, userid, url, status)
VALUES ('1234', 1, 'something.com', 'active');
This does not give the desired result since unique_screen_id will never be duplicate and thus the statement will insert the record. I can't remove the unique_screen_id out of the query since it also needs to be added into the table
Which query can I use so that if I insert the record above, it will check if userid and status and url are duplicate, and if they are ignore the statement (and otherwise insert the statement)?
Edit:
As requested my create table query:
CREATE TABLE `screens` (
`id` int NOT NULL AUTO_INCREMENT,
`unique_screen_id` varchar(20) DEFAULT NULL,
`userid` int DEFAULT NULL,
`status` enum('active','finished') DEFAULT 'active',
`url` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

I am not sure what your create table statement is like but you can add UNIQUE key:
UNIQUE (userid ,url, status)
Here is a demo
So first you create table like this(without UNIQUE KEY):
CREATE TABLE `screens2` (
`id` int NOT NULL AUTO_INCREMENT,
`unique_screen_id` varchar(20) DEFAULT NULL,
`userid` int DEFAULT NULL,
`status` enum('active','finished') DEFAULT 'active',
`url` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
then if you add this line
INSERT IGNORE INTO screens2 ( unique_screen_id, userid, url, status)
VALUES ( 1, '1', 'something.com', 'active');
and then this line
INSERT IGNORE INTO screens2 ( unique_screen_id, userid, url, status)
VALUES ( 1, '1', 'something.com', 'finished');
and then this line
INSERT IGNORE INTO screens2 ( unique_screen_id, userid, url, status)
VALUES ( 2, '1', 'something.com', 'finished');
all 3 lines will be inserted...
If you create your table like this:
CREATE TABLE `screens` (
`id` int NOT NULL AUTO_INCREMENT,
`unique_screen_id` varchar(20) DEFAULT NULL,
`userid` int DEFAULT NULL,
`status` enum('active','finished') DEFAULT 'active',
`url` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`),
unique(userid, url, status)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
Only two of the lines will be inserted and one will be ignored.
P.S. If you add UNIQUE key you will no IGNORE keyword with your insert statements.

As the user VBoka suggested the following demo displays the answer!
I needed to use a combination of the insert ignore statement and the Unique keyword!
Thanks!
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=5d19c458568ef9204c257b7ef6096eab

Related

How to avoid duplicate key error in mysql

I have a problem to get a next sequence id in my code. Though it was a legacy code i have to follow the same. Let me explain the logic which was followed.
CREATE TABLE `emp_seq` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1234 DEFAULT CHARSET=utf8
Above table used to get the next sequence id for the below table. and also emp_seq table will have only one entry for the id.
CREATE TABLE `emp_info` (
`id` BIGINT(8) UNSIGNED NOT NULL,
`name` VARCHAR(128) DEFAULT '',
`active` TINYINT(2) DEFAULT '1',
`level` MEDIUMINT(8) DEFAULT '100',
PRIMARY KEY (`id`),
KEY `level` (`level`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='employee information'
so whenever we trying to insert a new record to emp_info table, we are getting next sequence id from the table emp_seq by using below queries.
INSERT INTO emp_seq () VALUES ();
DELETE FROM emp_seq WHERE id < LAST_INSERT_ID;
Now the problem is, some times because of multiple asynchronous calls in the application, the same increment id has been shared to multiple records and trying to insert in the emp_info table and we are getting below error
"code":"ER_DUP_ENTRY","errno":1062,"sqlMessage":"Duplicate entry 1234 for key
Kindly help me how to resolve the issue.

Issue in insert query mysql error#1364

my query is
INSERT INTO `session_card` (`flags`, `history`, `showtime`, `session_id`, `card_id`, `card_mode`) VALUES ('', 'ö', '12', 9410, '256', 'rw')
and the table structure is
DROP TABLE IF EXISTS `session_card`;
CREATE TABLE IF NOT EXISTS `session_card` (
`id` int(11) NOT NULL,
`session_id` int(11) DEFAULT NULL,
`card_id` int(100) DEFAULT NULL,
`history` varchar(1000) DEFAULT NULL,
`flags` varchar(255) NOT NULL DEFAULT '',
`showtime` varchar(2000) DEFAULT NULL,
`card_mode` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
UNIQUE KEY `session_card_unique_key` (`session_id`,`card_id`,`card_mode`),
KEY `fk` (`session_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
COMMIT;
Now I dont understand what is the issue here also my phpmyadmin show only error code it doesnt give me the error expatiation. Any one can help me with this.
You need to have AUTO_INCREMENT on your id column, or you will need to pass a unique id manually every time you insert a row.
Change:
CREATE TABLE IF NOT EXISTS `session_card` (
`id` int(11) NOT NULL,
to:
CREATE TABLE IF NOT EXISTS `session_card` (
`id` int(11) NOT NULL AUTO_INCREMENT,
I would also suggest adding UNSIGNED as well since id's usually don't contain negative values.
In your schema, you have given id` int(11) NOT NULL but while inserting data you are not passing any value for id. as id is a not null constraint you should pass the value for id.
Modify you ID column to AUTO_INCREMENT flag
ALTER TABLE session_card MODIFY id int NOT NULL AUTO_INCREMENT
Make sure you table is empty before executing the above sql
If you are not setting a primary key id to Auto Increment then provide a value while inserting.
Otherwise, set it to AutoIncrement. This is better way to assigning a value.
INSERT INTO `session_card`
(`id`,`flags`, `history`, `showtime`, `session_id`, `card_id`, `card_mode`) VALUES
('1','', 'ö', '12', 9410, '256', 'rw')
Might be it's because of strick mode
Disable it:
SET sql_mode = '';
After this try insert query.
please make id key is auto increment
like following.
ALTER TABLE session_card MODIFY id int NOT NULL AUTO_INCREMENT
Otherwise add manually id at insertion time. like following.
INSERT INTO session_card
(id,flags, history, showtime, session_id, card_id, card_mode) VALUES
('1','', 'ö', '12', 9410, '256', 'rw')

How to do a Select in an insert MySQL

My question is how do i do a select of one attribute in my table.
I have the following table->
CREATE TABLE `Group` (
`group_id` varchar(10) NOT NULL,
`user_id` varchar(10) NOT NULL,
`group_creator` varchar(20) NOT NULL,
`group_name` varchar(50) NOT NULL,
`date_created` datetime DEFAULT NULL,
CONSTRAINT UC_Group UNIQUE (group_id,group_code,group_name)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `Group`
ADD PRIMARY KEY (`group_id`),
ADD KEY (`user_id`);
I would like to insert the user_id from another table called User. However it is not working.
My insert is as follows->
INSERT INTO `Group` (`group_id`, `user_id`, `group_creator`, `group_name`, `date_created`)
SET `group_id`=UUID(), `user_id`=(SELECT user_id FROM User WHERE username='TheDoctor'), `group_creator`='TheDoctor', `group_name`='HeroesUnited', `date_created`= CURRENT_TIMESTAMP();
Source
INSERT INTO Group
SELECT UUID(),user_id,'TheDoctor','HeroesUnited', CURRENT_TIMESTAMP()
FROM User
WHERE username='TheDoctor'

Can I add a Unique key on table creation in SQL?

I am trying to translate a collection of MySQL functions to SQL, and I'm having issues with a UNIQUE KEY issue:
-- -----------------------------------------------------
-- Table testform
-- -----------------------------------------------------
CREATE TABLE `testform` (
`FormId` INT(11) NOT NULL AUTO_INCREMENT,
`TTId` INT(11) NULL DEFAULT NULL,
`TestName` VARCHAR(100) NULL,
PRIMARY KEY (`FormId`),
UNIQUE KEY `TF_Composite` (`TTId`, `TestName`));
When I try and test this in SQLFiddle, it's giving me the error
Incorrect syntax near the keyword 'KEY'.
I have tried searching for this, but so far all I have come up with is "Unique Constraints". Is there a difference between a "Key" and a "Constraint" in SQL? And if so, how can I add this in the table creation statement?
Your syntax is all messed up. Please look at books on-line (MSDN).
https://msdn.microsoft.com/en-us/library/ms174979.aspx
The sample code below create a table in tempdb. This table automatically gets destroyed when the service is restarted.
-- Just a example, throw away after reboot
USE [tempdb]
GO
-- Create the table
CREATE TABLE DBO.TESTFORM
(
FORM_ID INT IDENTITY(1, 1) NOT NULL ,
TT_ID INT NULL,
TEST_NAME VARCHAR(100) NULL,
CONSTRAINT PK_FORM_ID PRIMARY KEY (FORM_ID),
CONSTRAINT UN_COMPOSIT UNIQUE (TT_ID, TEST_NAME)
);
-- Seventies Band
INSERT INTO TEMPDB.DBO.TESTFORM VALUES (1, 'John');
INSERT INTO TEMPDB.DBO.TESTFORM VALUES (2, 'Paul');
INSERT INTO TEMPDB.DBO.TESTFORM VALUES (3, 'Mary');
GO
-- Show data
SELECT * FROM TEMPDB.DBO.TESTFORM
GO
The image below shows the data in this table.
Try This.
CREATE TABLE testform (
FormId INT(11) NOT NULL AUTO_INCREMENT,
TTId INT(11) NULL DEFAULT NULL,
TestName VARCHAR(100) NULL,
PRIMARY KEY (FormId),
CONSTRAINT TF_Composite UNIQUE (TTId,TestName));
More Details..
For Better Understanding about Primary and Unique you can refer below page.
Primary and Unique Key Creation
For MySQL Database
CREATE TABLE `phone` (
`id` MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT,
`country` DECIMAL(5,0) UNSIGNED NOT NULL,
`area` DECIMAL(5,0) UNSIGNED NOT NULL,
`number` DECIMAL(8,0) UNSIGNED NOT NULL,
`extension` DECIMAL(5,0) UNSIGNED DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ix_phone` (`country`, `area`, `number`, `extension`),
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
For alter Table :
ALTER TABLEphone
ADD UNIQUE INDEXix_phone(country,area,number,extension);

Mysql how to add more than one value (in one box)

I am trying to add more than one value
INSERT INTO Requierments (item_ID, SName) VALUES (
05, 'Exotic Weapons''basic weapon');
is that possible? i have all ready tried | and & but i am not allowed to do that.
the idea is to demonstrate that item_ID requires more than one Sname.
and if no SName are needed, how do i code that, in the alter table it shows me that they are by default '0' for item_ID and '' for Sname, but when i try:
INSERT INTO Requierments (item_ID, SName) VALUES (
02, '');
or
INSERT INTO Requierments (item_ID, SName) VALUES (
02, );
error occurs. item_ID and SName are the primary key and foreign key to two different tables
CREATE TABLE `requierments` (
`item_ID` int(11) NOT NULL DEFAULT '0',
`SName` varchar(30) NOT NULL DEFAULT '',
PRIMARY KEY (`item_ID`,`SName`),
KEY `SName` (`SName`),
CONSTRAINT `requierments_ibfk_1` FOREIGN KEY (`item_ID`) REFERENCES `item` (`ID`),
CONSTRAINT `requierments_ibfk_2` FOREIGN KEY (`SName`) REFERENCES `talents` (`SkillName`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `talents` (
`SkillName` varchar(40) NOT NULL DEFAULT '',
`Bonus` varchar(30) DEFAULT NULL,
`Description` varchar(90) DEFAULT NULL,
`R_Str` int(11) DEFAULT NULL,
`R_WS` int(11) DEFAULT NULL,
`R_BS` int(11) DEFAULT NULL,
`R_Fel` int(11) DEFAULT NULL,
`R_Per` int(11) DEFAULT NULL,
`R_Int` int(11) DEFAULT NULL,
`R_Agi` int(11) DEFAULT NULL,
`R_WP` int(11) DEFAULT NULL,
`Talent_requiret` varchar(40) DEFAULT NULL,
PRIMARY KEY (`SkillName`),
KEY `Talent_requiret` (`Talent_requiret`),
CONSTRAINT `talents_ibfk_1` FOREIGN KEY (`Talent_requiret`) REFERENCES `talents` (`SkillName`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `item` (
`ID` int(11) NOT NULL DEFAULT '0',
`Name_` varchar(30) DEFAULT NULL,
`Weight` int(11) DEFAULT NULL,
`Value_` int(11) DEFAULT NULL,
`Availability` varchar(30) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Here are the 3 tables where i want to store in the requirement table what item_ID requires to be used under SName, since one item can be required to have more than one SName or none, it get confused on what to do.
The 'Exotic Weapons''basic weapon' syntax is interpreted as 'Exotic Weapons'basic weapon' (see the manual page on String Literals). You can store both, if you separate them with a special character like a comma or something ('Exotic Weapons,basic weapon'), but this is a bad idea, for the reasons that follow.
Anytime you are tempted to store multiple values in one column, you should have a new table to store each value and link it to the item_ID in question. This is called "normalization" - it makes your database more stable, your application code simpler, and everything just more likely to work as you move forward and modify things. Search for "database normalization" and read about how to do the kind of thing you are trying to do.
EDIT: It's still a little hard to tell what you're trying to do, but it looks like you just want to store multiple tuples in items. Example:
INSERT INTO Requierments (item_ID, SName) VALUES
(5, 'Exotic Weapons'),
(5, 'basic weapon');
Note that it should be 5, not 05. That's why INSERT INTO Requierments (item_ID, SName) VALUES ( 02, ''); fails. Also, you can't just omit a value and have blank space, like in your other example: INSERT INTO Requierments (item_ID, SName) VALUES ( 02, );
Honestly, it's very hard to tell what you're even trying to do here, and there seems to be some confusion about the basics of table structure and SQL syntax. For example, this statement is very confusing and unclear: "since one item can be required to have more than one SName or none, it get confused on what to do." If you can provide some more clarity about how you want the tables to relate to each other and where you are stuck, you will get more help from the SO community.