MYSQL Conditional Insert Into with multiple rows - mysql

Is it possible to insert multiple rows while checking each new row against a condition? I know that you can run a simple insert into with multiple rows
INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6),(7,8,9)
AND
INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6),(7,8,9)
ON DUPLICATE KEY UPDATE a=VALUES(a), b=VALUES(b), c=VALUES(c)
I am attempting to do something like this
INSERT INTO x_table(a,b,c)
SELECT VALUES(a),VALUES(b),VALUES(c)
FROM y_table
WHERE NOT EXISTS (SELECT * FROM x_table
WHERE a != VALUES(a)
AND b != VALUES(b))
Test Example (Tested and Working)
INSERT INTO `table` (id, timestamp, v1, v2, v3, v4, v5)
SELECT id, timestamp, v1, v2, v3, v4, v5
FROM (SELECT 6783 AS id, FROM_UNIXTIME('1580194194') AS timestamp, 1 AS v1, 0 AS v2, 1 AS v3, 0 AS v4, 45 AS v5
UNION ALL
SELECT 6845,FROM_UNIXTIME('1580194194'),1,0,1,0,107
UNION ALL
SELECT 6973,FROM_UNIXTIME('1580194194'),1,0,1,0,234
) y
WHERE NOT EXISTS (SELECT * FROM `table` x WHERE x.v1 = y.v1 AND x.v3 = y.v3 AND x.v5 = y.v5 ORDER BY TIMESTAMP DESC LIMIT 1)

You can write something like this:
INSERT INTO x_table
SELECT a, b, c
FROM (SELECT 1 AS a, 2 AS b, 5 AS c
UNION ALL
SELECT 4, 5, 6
UNION ALL
SELECT 7, 8, 9
) y
WHERE NOT EXISTS (SELECT * FROM x_table x WHERE x.a = y.a AND x.b = y.b)
Note that I think your EXISTS clause needs to use =, not != otherwise it will be true unless there is only 1 row in x_table which has matching a and b values to the first row to be inserted.
Demo on dbfiddle

You can do some checks in before insert trigger. Something like this:
CREATE TRIGGER `TRG_x_table_before_insert` BEFORE INSERT ON `x_table` FOR EACH ROW BEGIN
SET #found = NULL;
SELECT
a INTO #found
FROM
y_table
WHERE
a = NEW.a
AND b = NEW.b
;
IF #found IS NOT NULL THEN
SET #msg = 'Insert failed';
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = #msg;
END IF;
END

Related

Insert in the IF statement Query in mysql

Is there a way to run an insert query in the IF statement, As I know the syntax for if statement is
IF(conditon, execute if condition is True, execute if condition is False)
My question is whether if it is possible run an insert statement based on the conditions, like
IF((select count(*) from table where id = x) = 0, insert1, insert2)
insert1 will be a direct insert like
insert into table (col1,col2..) values (val1, val2..)
insert2 will fetch the previous value with the id whose count is not 0 and then do some logic and then insert the query looks like
insert into table (col1, col2, col3..) select val1,val1+val2,someOperation from table where id = x;
I think you need something like this :
IF( select count(*) from Table1 ) is null
begin
IF( select count(*) from Table1 ) is null
begin
--execute if condition is True
--insert condition
end
IF( select count(*) from Table1 ) is not null
begin
--execute if condition is False
--insert condition
end
end
MYSQL example :
IF ((select count(*) from table where id = x)) = 0
THEN
--insert into table (col1,col2..) values (val1, val2..)
ELSE
IF ((select count(*) from table where id = x)) != 0
THEN
--insert into table (col1, col2, col3..) select val1,val1+val2,someOperation from table where id = x;
END IF;
END IF;

Appending additional SQL tigger to existing trigger

I have the following SQL update trigger that works properly:
BEGIN
DECLARE myID INT;
SELECT user_id INTO myID FROM writer WHERE writer_id = NEW.writer_id;
IF (NEW.status_id = 2) THEN
INSERT INTO activity (
user_id,
work_id,
activity,
date_created
) VALUES (
myID,
NEW.work_id,
'confirmed',
now()
);
ELSE
INSERT INTO activity (
user_id,
work_id,
activity,
date_created
) VALUES (
myID,
NEW.work_id,
'modified',
now()
);
END IF;
END
I need to add an additional trigger as the following:
CREATE TRIGGER updateWorkStatus AFTER UPDATE ON writer_split
FOR EACH ROW
BEGIN
UPDATE work a
JOIN writer_split b
ON a.work_id = b.work_id AND a.current_version = b.version
SET a.status_id = 2
WHERE a.work_id NOT IN (
SELECT ab.work_id
FROM (SELECT s.work_id
FROM work w INNER JOIN writer_split s
ON w.work_id = s.work_id AND s.status_id != 2) ab
);
END;
when I run this create script, I am getting a syntax error. Any ideas?
For me i will use UPDATE work as a

Insert query based on number of rows

I want a query to insert a row into a table I know it is simple but the scenario is the table should not have more than 5 rows. If table has more than five rows I need to remove the old row(Or replace with new row ) (Based on the insert time stamp) then i need to insert a new row.If number of rows less than count 5 then i can directly insert a row.
Please share me the query.
How about something like this.
declare #count int
SELECT #count=COUNT(*)
from EP_ANSWERS
IF (#count<5)
// DO your insert here
ELSE
DELETE FROM TABLE
WHERE inserttimestamp = (SELECT x.inserttimestamp
FROM (SELECT MAX(t.inserttimestamp) AS inserttimestamp
FROM TABLE t) x)
// DO your insert here
If it is impossible for the table to have more than 5 rows:
DELETE FROM yourtable
WHERE 5 <= (SELECT COUNT(*) FROM yourtable)
AND yourtimestamp = (SELECT MIN(yourtimestamp) FROM yourtable)
;
INSERT INTO yourtable ...
;
If it is possible for the table to have more than 5 rows:
DELETE FROM yourtable
WHERE 5 <= (SELECT COUNT(*) FROM yourtable)
AND yourtimestamp NOT IN (SELECT yourtimestamp
FROM yourtable
ORDER BY yourtimestamp DESC
LIMIT 4)
;
INSERT INTO yourtable ...
;
It sounds like you want to put a trigger on the table to maintain this rule, in MySQL the something like this should work
CREATE TRIGGER trg__my_table__limit_rows
BEFORE INSERT
ON my_table
FOR EACH ROW
BEGIN
IF ((SELECT COUNT(1) FROM my_table) = 5)
BEGIN
DELETE FROM my_table
WHERE id = (SELECT MIN(id) FROM my_table) -- change this to fit your logic for which record should be removed
END
END
Some of the code here is in pseudo (you didn't wrote your schema), but i wrote where you need to complete your own code.
DECLARE #NumberOfRowsToInsert INT = -- select from the data you want to insert
DECLARE #MaxNumberOfRows INT = 5
DECLARE #NumberOfExistingRows INT
DECLARE #Query VARCHAR(MAX) = 'SELECT TOP #rows id FROM SomeTable ORDER BY createdDate ASC'
SELECT #NumberOfExistingRows = COUNT(*)
FROM SomeTable
SET #Query = REPLACE(#Query,'#rows',
CAST(#NumberOfRowsToInsert - (#MaxNumberOfRows - #NumberOfExistingRows))) AS VARCHAR(1))
CREATE TABLE #IdsToDelete(id INT PRIMARY KEY)
INSERT INTO #IdsToDelete
EXEC(#Query)
DELETE FROM SomeTable
WHERE id IN (SELECT * FROM #IdsToDelete)
-- insert here..

Mysql replace field from another table's field [duplicate]

This question already has answers here:
Oracle Replace function
(3 answers)
Closed 9 years ago.
I need to replace the Table1's filed values from Table2's values while select query.
Eg:
Table1:
Org Permission
--------------------------------------
Company1 1,3,7
Company2 1,3,8
Table2:
Permission Permission
--------------------------------------
1 Read
3 Write
7 Execute
8 Delete
I need like this:
Org Permission
--------------------------------------
Company1 Read,Write,Execute
Company2 Read,Write,Delete
I have been following your post since it was tagged in Oracle :D
In oracle it was looking in much possible ways, But in mysql you have to follow it with the help of procedure:
Schema:
create table table1 (org varchar(50), permission_id varchar(50));
create table table2 (permission_id int, permission_name varchar(50));
insert into table1 values ('Company1','1,3,7'),('Company2','1,3,8');
insert into table2 values (1,'Read'),(3,'Write'),(7,'Execute'),(8,'Delete');
Procedure:
DELIMITER $$
DROP PROCEDURE IF EXISTS `Update_Table_data`$$
CREATE PROCEDURE `Update_Table_data`()
BEGIN
declare max_row int;
declare p1 int;
Set p1 = 0;
SET max_row = (SELECT max(#i:=#i+1) AS row_num FROM table2 AS t,(SELECT #i:=0) AS foo);
label1: LOOP
set p1 = p1 + 1;
IF p1 <= max_row THEN
UPDATE Table1
SET permission_id =
replace(permission_id, (select permission_id from
(SELECT #i:=#i+1 AS row_num ,t.* FROM table2 AS t,(SELECT #i:=0) AS foo) a
where row_num = p1),
(select permission_name from
(SELECT #i:=#i+1 AS row_num ,t.* FROM table2 AS t,(SELECT #i:=0) AS foo) a
where row_num = p1));
Iterate label1;
END IF;
LEAVE label1;
END LOOP label1;
-- SET #x = p1;
END$$
DELIMITER ;
and then make a call to update your values :
call Update_Table_data;
Hope it helps :)
See SQLFiddle for initial data and this is resultant data SQLFiddle
UPDATE
organization
SET
permisson = (SELECT
GROUP_CONCAT(VALUE)
FROM
( SELECT
org,
SUBSTRING_INDEX(permisson,',',1) AS `permisson`
FROM
organization
UNION
SELECT
org,
SUBSTRING_INDEX(SUBSTRING_INDEX(permisson,',',2),',',-1) AS `permisson`
FROM
organization
UNION
SELECT
org,
SUBSTRING_INDEX(permisson,',',-1) AS `permisson`
FROM
organization
) AS t
JOIN
permission p
WHERE
p.p_id = t.permisson AND
t.org = organization.org
GROUP BY org
)
Try to replace your numbers using REPLACE.It work properly only when you are using single digit values for permission.
SQL = " SELECT Org, REPLACE(REPLACE(REPLACE(REPLACE(Permission,"1","Read'"),"3","Write'"),"7","Execute'"),"8","Delete'") as Permission FROM myTable "
REPLACE()

MySQL Count values in a column, Update and replace value which has a limit amount

I have a problem with a MySQL Update statement.
I have more than 100.000 Entries in the table. So my approaches were not successful. (see below)
First, I want to count the number of values (thats easy):
SELECT values1 ,count(values1) FROM table
GROUP BY value1
HAVING COUNT(value1) <= 1000;
Second, i want to replace some values of the column values1 which appears only <= 1000 times.
So I tried these statement:
Update table as t
SET t.value1 = "limitAmount"
WHERE EXISTS (select value1 from
(select * from table) as f Group by f.value1
Having count(f.value1) <= 1000);
When i tried this SQL statement, i received:
Error Code 1205. Lock Wait timeout exceeded. Try restarting transaction.
Try this
Update
table as t
SET
t.value1 = "limitAmount"
WHERE
EXISTS (select value1 from (select * from table) as f where f.value1 = t.value1 Group by f.value1 Having count(f.value1) <= 1000);
Notice where f.value1 = t.value1 condition in the subquery
This statement works:
UPDATE test SET val="BLUB"
WHERE val IN
(SELECT val FROM (SELECT val FROM test GROUP BY val HAVING COUNT(val) <2000) war);
alternative:
Adding Values to a separate table
INSERT INTO helpTable (Value1) (select val FROM test
Group by val
Having count(val) <= 2000);
Select
Update test as t
SET t.val = "BLUB"
WHERE NOT EXISTS (Select Value1 FROM helpTable as h WHERE t.val = h.Value1);