I have three tables, that match the following diagram:
And I need to delete some data from join_table, where a label column(table_right) and name column(table_left) match some criteria.
My solution is to use a temporary table:
create temporary table if not exists data_for_deletion
(select jt.id
from join_table jt
left join table_left tableLeft on jt.table_left_id = tableLeft.id
left join table_right tableRight on jt.table_right_id = tableRight.id
where tableLeft.name = 'name' and tableRight.label = 'label');
delete from join_table where id in (select id from data_for_deletion);
My question is: is there any other way to do such deletion without creating a temporary table?
You should be able to use MySQL's multi-table DELETE syntax:
DELETE jt
FROM join_table jt
JOIN table_left tl ON jt.table_left_id = tl.id
JOIN table_right tr ON jt.table_right_id = tr.id
WHERE tl.name = 'name' AND tr.label = 'label'
Note that since you have a WHERE clause which is dependent on columns in table_left and table_right there is no point in using a LEFT JOIN as it will be converted to an INNER JOIN anyway (see the manual).
Related
DELETE *
FROM ((disease
INNER JOIN dishead ON disease.heading = dishead.hid)
INNER JOIN disdes ON disease.description = disdes.did)
where disease.id = 9;
basically i have inserted the data using inner join and the data is stored against same product in multiple tables
Now i am trying to write query for deleting that inserted rows from all tables
You have to specify the tables to delete from
DELETE d, dh, dd
FROM disease AS d
JOIN dishead AS dh ON d.heading = dh.hid
JOIN disdes AS dd ON d.description = dd.did
WHERE d.id = 9
Note also that if these are foreign keys, you can configure them with ON DELETE CASCADE. Then you only have to delete from the parent table, and the rows that reference them will be deleted automatically.
I need all records from the URA table, joined on dobavljac for name of the dobavljac and all records from DOSTAVNICA table based on dostavnica.ura_id WHERE EXIST ura_id Join on gradilista for the name of gradilista.
Query:
$sql = "SELECT
ura.id,
ura.id_dobavljac,
ura.broj_racuna,
dobavljaci.id_dobavljac,
dobavljaci.naziv as dnaziv,
dobavljaci.oib,
dobavljaci.adresa,
dostavnica.ura_id,
dostavnica.id_dostavnica,
dostavnica.id_gradilista,
gradilista.id,
gradilista.naziv
FROM ura
INNER JOIN ura ON ura.id = dostavnica.ura_id
LEFT JOIN ura ON ura.id_dobavljac = dobavljaci.id_dobavljac
LEFT JOIN dostavnica ON dostavnica.id_gradilista = gradilista.id
";
Table schema:
and this is what I expect:
Try this one : A brief table structure would have helped. But based on the col names you have in the query I have posted my answer.
SELECT
ura.id,
ura.id_dobavljac,
ura.broj_racuna,
dobavljaci.id_dobavljac,
dobavljaci.naziv as dnaziv,
dobavljaci.oib,
dobavljaci.adresa,
dostavnica.ura_id,
dostavnica.id_dostavnica,
dostavnica.id_gradilista,
gradilista.id,
gradilista.naziv
FROM ura
INNER JOIN dobavljac ON ura.id_dobavljac = dobavljaci.id_dobavljac
INNER JOIN dostavnica ON ura.id = dostavnica.ura_id
WHERE EXISTS
(SELECT 1 from gradilista WHERE dostavnica.id_gradilista = gradilista.id)
I need to update multiple records in a table based upon the sum of some values in another table. Here is my query:
UPDATE aallinnot2 c SET c.Energ_Kcal = ( SELECT d.id1, SUM( c.Energ_Kcal)
FROM aaingred a
LEFT JOIN aaweight b ON a.unit = b.uni
LEFT JOIN aallinnot2 c ON a.mfdfsds = c.NDB_No
LEFT JOIN aalinfsds d ON a.fsdsnum = d.id1
WHERE d.own_id =42
GROUP BY id1 )
WHERE c.NDB_No
IN ( SELECT DISTINCT `fsdsnum`
FROM `aaingred`
WHERE `usernum` LIKE '42'
)
MySQL said:
#1093 - You can't specify target table 'c' for update in FROM clause
Unfortunately, I don't know how to get my values without referencing target table 'c'! Is there a workaround for this?
With the crazy table/column names and indecipherable logic, this might be the ugliest query I have ever seen. Congrats. :)
I think the following should work (or this approach). The main problem was untangling the group-by expression-- you need to give the database engine a dataset where each row in the target table is joined to a set that contains the updated value for that row. So here, select the new values in a sub-query, then join that sub-query to the original table.
EDIT Fixed some syntax
UPDATE
(
SELECT d.id1, SUM (c.Energ_Kcal) AS Sum_Energ_Kcal
FROM aaingred a
LEFT JOIN aaweight b ON a.unit = b.uni
LEFT JOIN aallinnot2 c ON a.mfdfsds = c.NDB_No
LEFT JOIN aalinfsds d ON a.fsdsnum = d.id1
WHERE d.own_id =42
GROUP BY id1
) d
,aaingred a, aallinnot2 d
SET Energ_Kcal = d.Sum_Energ_Kcal
WHERE d.id1 = a.fsdsnum
AND a.mfdfsds = aallinnot2.NDB_No
AND c.NDB_No IN (
SELECT DISTINCT `fsdsnum`
FROM `aaingred`
WHERE `usernum` LIKE '42'
);
I'm not sure about mysql, but with SQL Server the statement would be something like this:
UPDATE aallinnot2
SET Energ_Kcal = (
SELECT SUM( c.Energ_Kcal)
FROM aaingred a
LEFT JOIN aaweight b ON a.unit = b.uni
LEFT JOIN aallinnot2 c ON a.mfdfsds = c.NDB_No
LEFT JOIN aalinfsds d ON a.fsdsnum = d.id1
WHERE d.own_id =42)
WHERE c.NDB_No
IN ( SELECT DISTINCT `fsdsnum`
FROM `aaingred`
WHERE `usernum` LIKE '42')
You can't alias the table to be updated in the UPDATE clause, but you can in the FROM clause.
I am creating a view for my Database , I am joing 3 tables, Users,personal_info and contact_info, if you notice I have a lot of column names in my Select statement , since i don't want to include primary keys but it seems I have an error here, take a look
CREATE VIEW `payroll`.`new_view` AS
Select employee_id,employee_password,First_Name,Middle_Initial,
Last_Name,Date_Of_Birth,Beneficiaries,Home_Number,Address,Mobile_Number,Email_Address
From USER
LEFT JOIN personal_info on idUser = idPersonal_Info,
FULL JOIN contact_info on idUser = idContact_Info
The error is
ERROR 1146: Table 'payroll.full' doesn't exist
SQL Statement:
CREATE OR REPLACE VIEW `payroll`.`new_view` AS
Select employee_id,employee_password,First_Name,Middle_Initial,
Last_Name,Date_Of_Birth,Beneficiaries,Home_Number,Address,Mobile_Number,Email_Address
From USER
LEFT JOIN personal_info on idUser = idPersonal_Info,
FULL JOIN contact_info on idUser = idContact_Info
quote it with backtics: payroll.new_view
CREATE VIEW `payroll.new_view`
Error on:
LEFT JOIN personal_info on idUser = idPersonal_Info
you need to specify which column on which table equals which one on the other table, like
SELECT a,b,c from table1
LEFT JOIN table2
on table1.a= table2.columnY
in your case:
on USER.idUser = Personal_Info.idPersonalInfo
and the same for the 3rd Join
Another thing is the Comma at the end of the line:
LEFT JOIN personal_info on idUser = idPersonal_Info ,
it doesnt belong there.
I have a situation where a property table holds an address id (from the g_addresses table) and an applicant table also holds an address id from the g_addresses.
I'd like to left join these together but select all the fields in the table.
I know of using 'as' to make an alias for fields, but is there any way to produce an alias for a whole table?
SELECT *
FROM (`reference`)
LEFT JOIN `applicants` ON `applicants`.`id` = `reference`.`applicant_id`
LEFT JOIN `g_people` applicant_person ON `applicant_person`.`id` = `applicants`.`person_id`
LEFT JOIN `g_addresses` applicant_address ON `applicant_address`.`id` = `applicants`.`address_id`
LEFT JOIN `properties` ON `properties`.`id` = `reference`.`property_id`
LEFT JOIN `g_addresses` property_address ON `property_address`.`id` = `properties`.`address_id`
WHERE `reference`.`id` = 4
This produces a result containing only one address row and not both,
The row that is returned is the row from the final join and not the one previously, indicating it is overwriting when it is returned.
I don't think you should use masked references, like * or `reference`.*, in your case, because you may end up with a row set containing identical column names (id, address_id).
If you want to pull all the columns from the joined tables, you should probably specify them individually in the SELECT clause and assign a unique alias to every one of them:
SELECT
ref.`id` AS ref_id,
ref.`…` AS …,
…
app.`id` AS app_id,
…
FROM `reference` AS ref
LEFT JOIN `applicants` AS app ON app.`id` = ref.`applicant_id`
LEFT JOIN `g_people` AS ape ON ape.`id` = app.`person_id`
LEFT JOIN `g_addresses` AS apa ON apa.`id` = app.`address_id`
LEFT JOIN `properties` AS pro ON pro.`id` = ref.`property_id`
LEFT JOIN `g_addresses` AS pra ON pra.`id` = pro.`address_id`
WHERE ref.`id` = 4
Be more specific about columns you select
SELECT
applicant_address.*,
property_address.*,
applicants.*,
applicant_person.*,
properties.*
FROM (`reference`)
LEFT JOIN `applicants` ON `applicants`.`id` = `reference`.`applicant_id`
LEFT JOIN `g_people` applicant_person ON `applicant_person`.`id` = `applicants`.`person_id`
LEFT JOIN `g_addresses` applicant_address ON `applicant_address`.`id` = `applicants`.`address_id`
LEFT JOIN `properties` ON `properties`.`id` = `reference`.`property_id`
LEFT JOIN `g_addresses` property_address ON `property_address`.`id` = `properties`.`address_id`
WHERE `reference`.`id` = 4