DELETE multiple tables based on a query result - mysql

Our database didn't implement ON DELETE CASCADE so I need to create a script or a stored procedure to delete records in multiple tables given the results of Ids in a QUery:
I tried it in stored procedure but I cannot assign multiple rows in a variable:
CREATE PROCEDURE `Delete_card`(IN _status INT)
BEGIN
SET #IDs = SELECT ID FROM TABLE_ID WHERE Status=_status;
DELETE FROM TABLE_A WHERE ID IN (#IDs);
DELETE FROM TABLE_B WHERE ID IN (#IDs);
DELETE FROM TABLE_C WHERE ID IN (#IDs);
DELETE FROM TABLE_D WHERE ID IN (#IDs);
DELETE FROM TABLE_E WHERE ID IN (#IDs);
END

You can do it with a multi-table DELETE statement:
DELETE a, b, c
FROM TABLE_ID t
LEFT JOIN TABLE_A a ON a.id = t.id
LEFT JOIN TABLE_B b ON b.id = t.id
LEFT JOIN TABLE_C c ON c.id = t.id
..................................
WHERE t.Status = ?;
Change ? with the Status value that you want.
See a simplified demo.

Related

You can't specify target table 'table' for update in FROM clause in mysql

Need to delete data from table_a. We have to delete data from table_a. So table_a join with table_b(It is done using subquery).
delete from table_a where id in (SELECT GROUP_CONCAT(N.id) FROM table_a N
INNER JOIN table_b E ON N.form_id=E.form_id and N.element_id=E.element_id
WHERE N.option_value=0 AND E.element_type IN('checkbox','radio','select')
AND N.id BETWEEN 13000 AND 14001);
When i exeute the above query, getting error is given below
You can't specify target table 'table_a' for update in FROM clause
How to fix this issue.
I have tried with the below query. is it ok?
delete from table_a where id in (SELECT * FROM(SELECT GROUP_CONCAT(N.id) FROM table_a N
INNER JOIN table_b E ON N.form_id=E.form_id and N.element_id=E.element_id
WHERE N.option_value=0 AND E.element_type IN('checkbox','radio','select')
AND N.id BETWEEN 13000 AND 14001)tblTmp);
DELETE t1
FROM table_a t1
JOIN ( SELECT N.id
FROM table_a N
INNER JOIN table_b E ON N.form_id=E.form_id and N.element_id=E.element_id
WHERE N.option_value=0
AND E.element_type IN('checkbox','radio','select')
AND N.id BETWEEN 13000 AND 14001 ) t2 USING (id);

I want to update table value based on another table max value

I have two tables A and B(oracle database). Table B has two columns Id and mdate, where id is primary key. Table A has two columns Id and mdate where id is foreign key. I want to update table B mdate value which should be max mdate value from table A for matching Id.
Update b
set mdate= (select max(mdate) from a group by Id)
where b.id = a.id;
You're very close. The WHERE clause needs to be moved into the subquery, to make it a correlated subquery. Also, the parameter to UPDATE is a table name, not a column name.
UPDATE b
SET mdate = (SELECT MAX(mdate) FROM a WHERE b.id = a.id)
In MySQL you can also do it with a JOIN:
UPDATE b
JOIN (SELECT id, MAX(mdate) AS mdate
FROM a
GROUP BY id) AS a ON a.id = b.id
SET b.mdate = a.mdate
Update b
set(b.mdate) = (select MAX(a.mdate) from a where b.id = a.id)
where exists ( select 1 from a where b.id = a.id);
Thanks to Mr. Barmar.

UPDATE SET information from 3 tables

table_a (item_id, item_desc)
table_b (item_id, item_name)
table_c (item_name, item_desc)
I need to set table_a.item_desc=table_c.item_desc
No matter what am I doing I'm still getting errors.
This is my final work:
UPDATE table_a
SET table_a.item_desc = table_c.item_desc
FROM table_a
INNER JOIN table_b
ON table_a.item_id = table_b.item_id
INNER JOIN table_c
ON table_b.item_name = table_c.item_name;
You have syntax error. In MySQL you don't need to add FROM clause when using UPDATE with JOIN.
Also add table alias for better readability.
UPDATE table_a A
INNER JOIN table_b B ON A.item_id = B.item_id
INNER JOIN table_c C ON B.item_name = C.item_name
SET A.item_desc = C.item_desc ;
In MySQL the join part goes right after the update keyword, not to the end of the statement:
UPDATE table_a
INNER JOIN table_b ON table_a.item_id = table_b.item_id
INNER JOIN table_c ON table_b.item_name = table_c.item_name
SET table_a.item_desc = table_c.item_desc;
Try this as in Update JOIN will be used before SET
UPDATE table_a
INNER JOIN table_b ON table_a.item_id = table_b.item_id
INNER JOIN table_c ON table_b.item_name = table_c.item_name
SET table_a.item_desc = table_c.item_desc;

SQL Join over two tables

here is my problem:
I have two tables. Every entry of table A has several entries in table B matched over an ID. I now want to get all entries of table A with one data entry of table B - the one with the highest ID in this table.
Table A has an ID
Table B has an own ID and ID_OF_TABLE_A (for the relation between both)
Table A has one to many relation to Table B. I want all Entries of Table A, matched with the one with the highest ID out of B. Is there any way to realize this in an SQL Statement? I tried all kinds of joins since I need the information of that matched entry in the outcome of the select.
How about
SELECT *
FROM tableA a
INNER JOIN tableB b ON a.ID = b.ID_OF_TABLE_A
WHERE b.ID = (SELECT MAX(ID) FROM tableB c WHERE b.ID = c.ID)
Try this:
SELECT a.*, b.*
FROM tableA a
LEFT OUTER JOIN (SELECT b.*
FROM tableB b
INNER JOIN (SELECT ID_OF_TABLE_A, MAX(ID) bID
FROM tableB
GROUP BY ID_OF_TABLE_A
) c ON b.ID_OF_TABLE_A = c.ID_OF_TABLE_A AND b.ID = c.bID
) AS b ON a.ID = b.ID_OF_TABLE_A;
You can use an inline view where you filter the rows you need from table b with the help of the grouping clause and max function like so:
select a.*, b.*
from a
join (
select max(id) as id_b_max, id_a
from b
group by id_a
) b
on a.id = b.id_a;
Tested with:
create table a(id int);
create table b(id int, id_a int);
insert a values (1);
insert b values(1, 1);
insert b values(2, 1);
insert b values(3, 1);
select a.id, max(b.id)
from table_a a join table_b b on a.id = b.table_a_id
group by a.id
This should work. prefilter out the max id of the ID_OF_TABLE_A. and then join on that id.
SELECT A.*, B.*
FROM A
INNER JOIN ( SELECT max( ID ) AS id, ID_OF_TABLE_A
FROM B
GROUP BY ID_OF_TABLE_A) AS grp_b
ON grp_b.ID_OF_TABLE_A = a.ID
INNER JOIN B ON b.ID = grp_b.id

DELETE multiple tables where at least one is empty

I'm deleting certain rows from multiple tables like this:
I would like to clean up certain tables after an entry from the main table has been removed. I know the ID of that entry (which is the fid in all other tables) but not every table contains related data.
This is what I came up with:
DELETE a, b, c
FROM tableA AS a
LEFT JOIN tableB AS b
ON a.fid = b.fid
LEFT JOIN tableC AS c
ON a.fid = c.fid
WHERE a.fid = 123
This only works if tableA contains at least one row with a fID of 123
How can I delete remove certain rows from tableB and tableC when tableA has no matching row?
I think the easiest approach is three delete statements:
delete tableA where fid = 123;
delete tableB where fid = 123;
delete tableC where fid = 123;
If you want to do this as one statement, use left outer join but start with the list of ids to delete:
delete a, b, c
from (select 123 as fid
) todelete left outer join
tableA a
on todelete.fid = a.fid left outer join
tableB b
on todelete.fid = b.fid left outer join
tableC c
on todelete.fid = c.fid;
Untested Query using + operator as in Oracle.
Check if it would help:
DELETE a, b, c
FROM tableA AS a , tableb as b, tableC as c
and a.fid = b.fid(+)
and a.fid = c.fid(+);