I am trying to delete record from 3 tables in 1 sql query in php. First, I tried it with delete records from two tables. This is the query for that:
DELETE pa, pr FROM pollanswers pa INNER JOIN pollresults pr ON
pa.PollQuestionId=pr.PollQuestionId WHERE pa.PollQuestionId = '123';
The problem is, what if there is no PollQuestionId in one of these table.. And other thing after that how to integrate it with third table?
Thanks.
You should not delete from multiple tables in one query.
You can define foreign key constraints on the tables with ON DELETE CASCADE option.
Then deleting the record from parent table removes the records from child tables.
Check this link : http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
I have figured it out guys.. Thanks for your effort...
here is the query to join 3 tables:
DELETE po, pa, pr FROM posts po
LEFT JOIN pollanswers pa ON pa.PollQuestionId=po.PostId
LEFT JOIN pollresults pr ON pr.PollQuestionId=po.PostId
WHERE po.PostId = '123';
To join a third table, you could add another inner join:
DELETE pa, pr FROM pollanswers pa
INNER JOIN pollresults pr ON pa.POllQuestionID=pr.PollQuestionId
INNER JOIN pollwhatevers pw ON pw.whatevercolumn=pa.PollquestionID
WHERE pa.PollQuestionId = '123';
But if you want to join it to a table that is the result of joining PollResults and PollAnswers, you may want to consider using a temporary table. See this link for more information,I'm not sure I can explain it as well as this does:
http://devzone.advantagedatabase.com/dz/webhelp/Advantage7.1/adssql/using_temporary_tables_in_sql_statements.htm
Related
I have 3 tables, tb_item, tb_branch, tb_department, tb_division.
As you can see:
tb_division is under tb_department
tb_department is under branch
tb_branch has no superior
for example if I want to retrieve item_id 1 or 2 or 3 then this should be the result
If I want to retrieve item_id 2 then it will show the department and branch.
My problem is that I can nested join them if if I know the item is related to a specific table but in this case since tb_item can be related to tb_division or tb_department and tb_branch I don't know what query should I formulate.
Changing the database design is not an option since this design is already implemented.
SELECT column-names
FROM table-name1 JOIN table-name2
ON column-name1 = column-name2
WHERE condition
Never Mind guys. I managed to solved it myself. been struggling since I thought I need to do tons of subqueries. Thanks for the answers tho.
SELECT
i.item_id,
dv.division_name,
COALESCE(dept.department_name, dept2.department_name) AS department_name,
COALESCE(br.branch_name, br2.branch_name, br3.branch_name) AS branch_name
FROM
tb_item AS i
LEFT JOIN
tb_division AS dv
ON i.division_id = dv.division_id
LEFT JOIN
tb_department AS dept2
ON dv.department_id = dept2.department_id
LEFT JOIN
tb_branch AS br2
ON dept2.branch_id = br2.branch_id
LEFT JOIN
tb_department AS dept
ON i.department_id = dept.department_id
LEFT JOIN
tb_branch AS br3
ON dept.branch_id = br3.branch_id
LEFT JOIN
tb_branch AS br
ON i.branch_id = br.branch_id
I have a table which contains records of a 'widget' many of the columns contain just the Id of a record in a different table. When editing the widget record users are allowed to do a save even if it is incomplete. They can open it later and continue.
The problem I have, is when it is incomplete my query returns nothing because the where clause contain fields which have default 0 in them and there is no match in the other tables. Here is a sample of script which illustrates this problem.
select Client,Make,Model,Shape
from
widget,clients,makes,models,shapes
where
widget.ClientId = '3' and
widget.MakeId = makes.Id and
widget.ModelId = models.Id and
widget.ShapeId = shapes.Id
I am building this query dynamically using PHP so am trying to keep it as simple as possible. All sugestions welcome, thanks.
The problem is that you are using an implicit inner join (implicit meaning that you do the join in the where clause). Inner joins return matching records only, therefore if some of the data are incomplete, no records will be returned.
Use an outer join instead, that return all records from one of the tables in the join and the matching records from the other table (MySQL does not support full outer join, but this is not relevant here anyway).
Based on your description widget table is your main table, so use left join to join all other tables on widget to get the widget even if it is incomplete:
select c.Client, m.make, md.model, s.shape
from widget w
left join clients c on c.id = w.ClientId
left join makes m on m.id = w.MakeId
left join models md on md.id = w.ModelId
left join shapes s on s.id = w.ShapeId
select c.Client, m.make, md.model, s.shape
from widget w
join clients c on c.id = w.ClientId
join makes m on m.id = w.MakeId
join models md on md.id = w.ModelId
join shapes s on s.id = w.ShapeId
Use Joins instead of multiple tables in FROM Clause.
Instead of direct join use LEFT JOIN so that no matter if there is records from other tables, still first table entries will be returned:
SELECT Client, Make, Model, Shape
FROM widget
LEFT JOIN clients ON widget.ClientId = widget.Id
LEFT JOIN makes ON widget.MakeId = makes.Id
LEFT JOIN models ON widget.ModelId = models.Id
LEFT JOIN shapes ON widget.ShapeId = shapes.Id
WHERE widget.ClientId = 3
Table columns should be in lower case
Table names should be in singular form, e.g. model, shape
Foreign keys should be in other table. Instead of widget having ModelId, model should have widget id
I may be wrong if relations are different
I am trying to join two tables together in a view. My first table combines two tables but now I am trying to join that table to a second table. I am trying to use a join to make sure the second table which contains roles which are performed by the user, matches up with the first table but if there are no records in the second table, I still want all the records from table 1. I know my explanation is a little confused, so my code is as follows:
CREATE VIEW `data` AS SELECT
`information`.`username`, `information`.`department`,
`information`.`company`, `information`.`title`,
`information`.`internal_number` AS `user_internal_phone`,
`information`.`external_number`AS `user_external_phone`,
`information`.`mail`, `information`.`cn` AS `name`, `information`.`hours`,
`information`.`languages`, `information`.`functions`,
`information`.`service` AS `contact_point_name_one`,
`information`.`subservice` AS `contact_point_name_two`,
`information`.`internal_phone` AS `contact_internal_phone`,
`information`.`external_phone` AS `contact_external_phone`,
`information`.`keywords`, `information`.`description`,
`information`.`provided_by`, `information`.`id`,
GROUP_CONCAT(`staff_roles`.`role` SEPARATOR ', ') AS `roles`,
`staff_roles`.`user`
FROM `information`
CROSS JOIN `staff_roles` ON `information`.`username` = `staff_roles`.`user`;
I get an error when I do an outer join and a cross join and an inner join both return rows where there is a row in both tables yet I want it to display the rows where there is nothing in the second table as well. The purpose of using a join is so that, where there is a match, the row from table 2 should match the row on table 1
Use LEFT JOIN. The LEFT JOIN keyword returns all rows from the left table (table1), with the matching rows in the right table (table2). The result is NULL in the right side when there is no match.
Just replace your CROSS JOIN with LEFT JOIN
Simply use LEFT JOIN instead of CROSS JOIN:
CREATE VIEW `data` AS SELECT
...
FROM `information`
LEFT JOIN `staff_roles` ON `information`.`username` = `staff_roles`.`user`;
Take a look at http://www.w3schools.com/sql/sql_join_left.asp for further details about why LEFT JOIN.
I have four tables (in [] are columns):
users [id]
products [id]
productRatings [id,value,user,product]
comments [id,product,user]
I would like to select/and ultimately delete productRatings where there are no associated comment by the same user for that product. That is, if user has rated product but did not comment, that rating should be deleted.
I believe I could achieve that by using two queries, first:
SELECT user, product FROM productRatings
and then for each row:
SELECT COUNT(*) FROM comments WHERE product=productRatings.product AND user=productRatings.user
and then something like
if $queryAbove==0 : DELETE FROM productRatings WHERE id=productRatings.id
I would like to solve this via JOIN and learn more by example rather than dig through JOIN tutorials.
You only need the productratings and comments table - the following works:
delete pr
from productratings pr
left join comments c
on pr.userid = c.userid
and pr.productid = c.productid
where c.productid is null
And there's a demo here: http://sqlfiddle.com/#!9/89575/1
DELETE FROM `productRatings` WHERE productRatings.id NOT IN (
SELECT productRatings.id FROM `productRatings` JOIN `comments` ON productRatings.user = comments.user AND productRatings.product = comments.product )
I'd make copies of the tables in question and test that the above works on the test tables before using this on your production tables.
Basically, the nested select will return all productRatings id's that the user who wrote the rating also made a comment on. Using NOT IN, it will delete all ratings that the user who made the rating didn't also comment.
As pala_ highlighted in the comments below, because this method uses nested sql, it will perform worse than a method that only uses joins on larger tables.
You should be able to just join the fields in the query and then check if the comment is empty, like so...
DELETE FROM `productRatings`
JOIN `comments` ON (`productRatings`.`product` = `comments`.`product`)
WHERE `comments`.`comment_field` IS NULL
AND `productRatings`.`user_id` = ?;
The IS NULL may need to be replaced with = '' depending on the database engine you use.
Remember to test on a testing instance of the DB first!
DELETE FROM productRatings WHERE id IN (SELECT pr.id FROM productRatings pr
LEFT JOIN comments c on c.product = pr.product
WHERE c.user = pr.user
AND pr.comment IS NULL)
I have two table category and subcategory
I am trying to delete record from this table using mysql query
Query is=
$sql="Delete t1, t2 From category as t1
INNER JOIN subcategory as t2 on t1.c_id = t2.c_id
WHERE t1.c_id='$del_c_id' ";
This query only delete row from category(t1) whose primary key used into subcategory(t2) table.
Not delete row from category(t1) whose primary key not used in subcategory(t2).
You need to use a LEFT JOIN instead of INNER JOIN. By definition LEFT JOIN returns all results from t1, even if they don't have a match in t2.
See this link for more info on join types:
http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html
Try CASCADE option in mysql. Subcategory will be deleted automatically if you delete the category. You need to use the InnoDB storage engine to use this feature.
Here is the accepted answer