insert if not exists else just select in mysql - mysql

I have one mysql table 'alfa' that will contain the primary key of another table 'beta' in one column. But if the entry in 'beta' can not be found I want to insert the value in 'beta' and use the new key in 'alfa'. Can I do this in one query somehow ?
I currently have:
INSERT INTO alfa SET c1=(SELECT id FROM beta WHERE name = 'john');
which works fine when 'john' exists in the table, but fails otherwise. So could I improve it to let the new name be inserted and selected if it is not already there ? id is auto_incremented.
I have tried to looking at IF but have not yet found out how to use IF outside the SELECT, is that possible ?
I know I can do it in several queries but I am talking with a remote database so could be nice to do it all at once.
For example the tables could have been created like this:
CREATE TABLE alfa (
c1 int,
PRIMARY KEY (c1)
)
CREATE TABLE beta (
id int auto_increment,
name varchar(255),
PRIMARY KEY (id)
)
so alfa.c1 should refer to the beta.id values.
In short I want to do:
insert the id for john from the beta table into c1 in alfa, if john does not exist in beta then insert john into beta and insert the new auto incremented id for john into c1 in alfa.

I'll have a go, but bear in mind that coming from a Microsoft SQL background, and I'm not familiar with the exact structure of your tables, so some of the the SQL is probably a bit ropey.
IF (SELECT COUNT(*) FROM beta WHERE name = 'John' > 0)
UPDATE alfa SET c1=(SELECT id FROM beta WHERE name = 'John')
ELSE
BEGIN
INSERT INTO beta (name) VALUES ('John')
INSERT INTO alfa (c1) VALUES (LAST_INSERT_ID())
END
Hope this is of some help.

Related

MySQL - How to insert or update from source table to target table with different Keys?

I have 2 tables with different structures.
CREATE TABLE test1
(
id INTEGER PRIMARY KEY,
EmpName VARCHAR(50),
Empid INTEGER
);
CREATE TABLE test2
(
Empid INTEGER PRIMARY KEY,
EmpFName VARCHAR(50),
EmpLName VARCHAR(50)
);
Is there a way to insert rows from test2 table into test1? If the row exists in test1 it should update the row as well. I think it's possible with Merge statement but it's not available for MySQL. Is there a similar function like this in MySQL?
I've looked into INSERT ... ON DUPLICATE KEY UPDATE but the tables should have the same primary keys.
I think this can help you.
Create Trigger to detect when insert/update data in your table test2.
Inside Trigger use REPLACE INTO to change data in your table test1.
Please check this link for additional of REPLACE INTO command.
Is there a way to insert rows from test2 table into test1? If the row exists in test1 it should update the row as well
UPDATE test1
JOIN test2 USING (Empid)
SET test1.EmpName = CONCAT_WS(' ', EmpFName, EmpLName)
Pay attention - EmpName max length is 50 whereas total length of combined name may be up to 50+1+50=101, so the combined value may be truncated. Increase max length for EmpName.
If you need to perform this operation automatically when the data in test2 is inserted/updated then use AFTER INSERT and AFTER UPDATE triggers, like
CREATE TRIGGER tr
AFTER INSERT -- and the same trigger on AFTER UPDATE event
ON test2
FOR EACH ROW
UPDATE test1
SET EmpName = CONCAT_WS(' ', NEW.EmpFName, NEW.EmpLName)
WHERE test1.Empid = NEW.Empid;

SQL normalized data INSERT WHERE NOT EXISTS ; ON DUPLICATE KEY UPDATE

i am using MySql Workbench version 6.3.9 with mySql 5.6.35.
i have the following tables:
EQUIPMENT
eID | caochID | eName
COACH
coachID | coachName
SQLfiddle prepared http://sqlfiddle.com/#!9/e333d/1
eID is a primary key. there are multiple coachID's in different equipment, so there will be duplicate coachIDs with different equipment, but the eID will be unique as it is a primary key.
REQUIRED
i need to insert a row in the equipment table, if it does not already exist. If it exists, do nothing.
various posts online have pointed me towards two options:
a) INSERT...ON DUPLICATE KEY UPDATE...
b)INSERT...WHERE NOT EXISTS
PROBLEM i have problems with both of these solutions. for the first solution (ON DUPLICATE KEY UPDATE) the query inserts the row as required but does not update the existing row. instead it creates a new entry. for the second solution (WHERE NOT EXISTS) i get an error : SYNTAX ERROR: 'WHERE' (WHERE) is not a valid input at this position.
the sql query doesnt need to make any joins. i listed both tables so that you can see how they are related. the insert query i need will only insert for the equipment table.
You can insert by using a tmp table and ensuring that the same record is not existing from current table. Add limit 1 to ensure only one record is inserted. Below query will not insert since 1 and small ball exists.
INSERT INTO `Equipment` (`c_id`, `eName`)
SELECT * FROM (SELECT '1', 'small ball') tmp
WHERE NOT EXISTS (
SELECT c_id FROM Equipment WHERE `c_id`='1' and `eName` = 'small ball'
) LIMIT 1;
NOT EXISTS
insert into table2 (....) --- all if not columns ... destination
select ....
from table1 t1 --- source of data to check
where not exists (
select 1
from table2 t2
where t2.col = t1.col --- match source and destination table making sure table1 data is not in table2
)

How to insert if not exists with selecting from same table?

I have my table schema in H2 db as follows:
create table if not exists Test ( id bigint not null,name varchar(255), primary key (id) );
alter table Test add constraint if not exists Test_NAME UNIQUE (name);
I want to insert a value for the name attribute as 'Default' if it does not exist in the table by selecting the latest id value from the table and increment it by one.
Example:
Do not insert if an entry for name = Default already exists.
ID | Name
1 | Default
Insert if an entry for name = Default does not exists.
ID | Name
1 | ABC
2 | XYZ
For the id column, find the max id and increment it by one. In this case, insert id=3 and name=Default.
My query is as follows:
INSERT INTO Test (id , name)
SELECT max(id) + 1, 'Default' from Test
WHERE NOT EXISTS (SELECT * FROM Test where name='Default');
However, it gives me an error saying:
NULL not allowed for column "ID"; SQL statement
as it applies the where condition on the inner select statement.
I also tried:
MERGE INTO Test KEY(name) VALUES (SELECT MAX(id) + 1 from Test, 'Default');
It gives an error because, merge tries to update with the new values.
If it finds 'Default', it will update the row with new id causing primary key violation.
Is there a better way to do this? How can I make the query work?
You are massively overcomplicating this. Define the id field as auto increment and place a unique index on the name field. The unique index prevents duplicate names to be inserted, while the auto increment increases the value of the id field by 1 (by default) if the insert is successful.
I updated id to auto increment and the following query work flawlessly
INSERT INTO Test (name) select * from (select 'Default') as tmp WHERE NOT EXISTS (SELECT name from Test where name='Default');
when you run your query first time, no record found in table so, it give error 'null' there, so if you add IFNULL() function there as below
INSERT INTO Test (id , name)
SELECT **IFNULL**(max(id),0) + 1, 'Default'
FROM Test
WHERE NOT EXISTS (SELECT * FROM Test where name='Default');

How to set username using id in mysql

I have a database table in mysql
create table userstable
(
id int not null auto_increment,
name varchar(80) not null,
username varchar(80) not null,
primary key(id)
);
How to add new row in mysql database, so that username will be 'name'+('id'*100)
Example :
ID name username
1 A A100
2 B B200
3 C C300
4 user user400
You need trigger for that process. Create the following trigger
CREATE TRIGGER username_change
BEFORE INSERT ON userstable
FOR EACH ROW
BEGIN
SET NEW.username = CONCAT(NEW.name,(NEW.id*100));
END
OR
INSERT INTO userstable (id,name, username) VALUES (2, 'B', CONCAT(name,(id*100)));
Try this.
You'll need to write a trigger or update the field after insertion. A similar question provides more insight:
Can you access the auto increment value in MySQL within one statement?
As #ArunKrish correctly pointed out, you may use TRIGGER to update the data as part of the insert. Another option is to use view:
CREATE VIEW v1 AS
SELECT id,name,CONCAT(name,id*100) AS username FROM userstable;
You may also use the query as-is, without view:
SELECT id,name,CONCAT(name,id*100) AS username FROM userstable;

Is there a way to insert an auto-incremental primary id with a prefix in mysql database?

I'm trying to insert a data as a primary ID that has one alphanumerical value and two numerical value in MySQL database. This data will auto incrementally generate number, but the alphanumerical value will be fixed. Like, D1, D2....D54, D55, D56 etc. Here, 'D' is always the same, but the number will be automatically incremented. Is there any way to do this?
First of all it's unadvisable to do so, like others commented, you can have this id value generated on the fly.
But if nonetheless you want it your way there're at least two ways to do so:
More or less reliable way involves using a separate table for sequencing and a trigger
Schema:
CREATE TABLE Table1_seq
(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
);
CREATE TABLE Table1
(
`id` VARCHAR(10) NOT NULL PRIMARY KEY DEFAULT '',
...
);
Trigger:
DELIMITER $$
CREATE TRIGGER tg_bi_table1
BEFORE INSERT ON table1
FOR EACH ROW
BEGIN
INSERT INTO table1_seq() VALUES();
SET NEW.id = CONCAT('D', LPAD(LAST_INSERT_ID(), 4,'0'));
END$$
DELIMITER ;
Then you just insert your rows to table1
INSERT INTO Table1 () VALUES (),(),();
And you'll get
| ID |
---------
| D0001 |
| D0002 |
| D0003 |
Here is SQLFiddle demo
Unreliable way is to generate your new id on the fly in INSERT statement itself
INSERT INTO Table1 (id, ...)
SELECT CONCAT('D', LPAD(COALESCE(SUBSTR(MAX(id), 2), 0) + 1, 4, '0')),
...
FROM table1
Here is SQLFiddle demo
The problems with this approach:
Under heavy load two concurrent sessions can grab the same MAX(id) value and therefore generate the same new id leading to the failure of insert.
You can't use multi-insert statements
We can't set auto-increment for alphanumeric. In your case if D is always same then no need to add it to your pk field. Keep your constant in a separate field and add it when you select.