MYSQL update with nested subquery - mysql

I have 3 tables in this format:
Table Child:
id|parent_id|grandparent_id
1 1 null
2 2 null
3 3 null
Table Parent:
id|grandparent_id
1 1
2 1
3 2
Table GrandParent:
id
1
2
I need to run a query that updates grandparent_id column in Child table based on the grandparent_id in Parent table. So the correct final form of Child table will be:
Table Child:
id|parent_id|grandparent_id
1 1 1
2 2 1
3 3 2
This is the query I have at the moment but it returns more than 1 row which is wrong:
update child set grandparent_id = (
select gpd.id from GrandParent gp, Parent p
where p.grandparent_id = gp.id)
where 1

You can use the following query to get the UPDATE:
UPDATE Child SET Child.grandparent_id = (
SELECT GrandParent.id
FROM GrandParent INNER JOIN Parent ON GrandParent.id = Parent.grandparent_id
WHERE Parent.id = parent_id
) WHERE Child.grandparent_id IS NULL;
Demo: http://sqlfiddle.com/#!9/894e97/1/0 (modified table content to show the UPDATE is working).
Hint: Your "correct" example is wrong: GrandParent of Parent with id = 2 is 1!

Please give a try on the below query:
Update child c,parent p
set c.grandparent_id = p.grandparent_id
where c.id = parent.id
and c.grandparent_id = ' '

Related

Avoid duplicates on MySQL update

I have a many-to-many relation table like this
element_a
element_b
1
2
1
3
2
1
2
3
3
1
3
3
I want to replace element_a with id 2 by id 1
UPDATE mytable x
SET x.element_a = 1
WHERE x.element_a = 2;
Since there is an unique index on (element_a, element_b ), this will result with duplicates error.
How can I execute my query without MySQL Error 1062 ?
You can use an update with LEFT JOIN:
UPDATE mytable x
LEFT JOIN mytable t ON t.element_b = x.element_b AND 1 = t.element_a
SET x.element_a = 1
WHERE
x.element_a = 2 AND t.element_a IS NULL
If t.element_a IS NOT NULL then pair element_a, element_b already exists in your table. Thus adding t.element_a IS NULL in the WHERE clause prevents UPDATE in case of duplicates.
Demo here

Get Minimum data id When using JOIN

I have Table Structure as below
And My Query is as below
SELECT *,MIN(node.rnode) AS minRnode
FROM final_mlm AS node,
final_mlm AS parent
where node.lnode BETWEEN parent.lnode AND parent.rnode AND parent.id = 1
AND node.placement='l'
This query is working quite fine but my requirement is I need an id which have minRnode As given in query in output..
What i have tried
SELECT *, MIN(node.rnode) as minn
FROM (
SELECT * FROM final_mlm AS node,
final_mlm AS parent
where node.lnode BETWEEN parent.lnode AND parent.rnode
AND parent.id = 4
AND node.placement='l'
) as t on t.rnode=node.minn
But this returns an error maybe for duplicate of id.
This is my live code In Sql Fiddle.
My output for First Woking query is
id sponserid level lnode rnode placement id sponserid level lnode rnode placement minRnode
3 2 2 21 22 l 1 0 0 1 24 6
So as per this output i need an id from table Which have minRnode(Monimum Rnode) = 6
Here is the solution for your problem:
SELECT id
FROM final_mlm
WHERE rnode IN (SELECT MIN(node.rnode)
FROM final_mlm AS node
INNER JOIN final_mlm AS parent
ON node.lnode BETWEEN parent.lnode AND parent.rnode
WHERE parent.id = 1
AND node.placement='l')
Link to the demo:
http://sqlfiddle.com/#!9/29e8d8/59

MYSQL Join tables with no unique id on multiple columns

I have the following tables:
Table Main:
TestNumber PassageNumber QuestionNumber
1 1 1
1 1 2
1 1 3
1 2 1
1 2 2
1 2 3
Table Child:
TestNumber PassageNumber QuestionNumber User SelectedAnswer
1 1 1 X A
1 2 2 X B
I want to show the data in main table that is not in child table based on a test number and user. So the results i am looking for are the following where the rows from main table are the ones NOT in child:
TestNumber PassageNumber QuestionNumber
1 1 2
1 1 3
1 2 1
1 2 3
I have tried the following query and variations with no luck:
SELECT a.passagenumber, a.questionnumber FROM Main a left outer join
Child b on a.testnumber=b.testnumber where b.user = 'X'
and b.testnumber=1 and a.testnumber=1 and b.selectedanswer is not null
I understand if i had a unique id this would be easy to solve but in this case that is not an option. Any help would be much appreciated.
I thin you can use not in
SELECT a.passagenumber, a.questionnumber FROM Main a
where ( a.testnumber, a.passagenumber, a.questionumber)
not in ( select b.testnumber, b.passagenumber, b.questionumber
from Child b where b.user = 'X' )
Can you join the tables on the three fields, using left join and where the child table value is null?
SELECT p.TestNumber
,p.PassageNumber
,p.QuestionNumber
FROM Parent p
LEFT JOIN Child c ON c.TestNumber = p.TestNumber
AND c.PassageNumber = p.PassageNumber
AND c.QuestionNumber = p.QuestionNumber
AND c.[User] = 'X'
WHERE c.TestNumber IS NULL;

MySQL Get Parent With Child Rows Together

i have searched for questions like this and although many are similars, are not answering exact my questions and queries not work.
Assuming we have the following table
id category_name parent_id
------------------------------------
1 test 0
2 test1 0
3 new_cat 1
4 new_catx 2
5 cat5 1
I want an sql query where the output will be like this
id category_name parent_id
------------------------------------
1 test 0
3 new_cat 1
5 cat5 1
2 test1 0
4 new_catx 2
In sort the output query is sorted based on parent_id. The parent_id = 0 is the root category, then child are following, and then again another parent with it's child. etc
This will work for a 1-level tree, i.e. for a tree containing only parents and their children:
SELECT *
FROM mytable
ORDER BY CONCAT(IF(parent_id=0, '', parent_id), id)
Demo here
Ideally you should use a mapping table for this, to make your solution cleanly scalable. Change your original table struct to
id category_name
---------------------
1 test
2 test1
3 new_cat
4 new_catx
5 cat5
...and have a parent mapping table, like so:
id parent_id
---------------------
3 1
4 2
5 1
Then you would simply modify Giorgos Betsos' excellent query to read:
select t.id, t.category_name, p.parent_id
from testtable t left outer join parents p
on t.id = p.id
ORDER BY CONCAT(IF(p.parent_id is null, '', p.parent_id), t.id);

Get parent with more than 2 child

Table structure:
| id | parent |
1 0
2 1
3 1
4 2
5 2
6 2
How can I get the id of the parent row that have more than 2 childs ?
(in the above case should return only the id=2 row)
Try this query
SELECT *
FROM tablename
WHERE id IN
(
SELECT parent
FROM tablename
GROUP BY parent
HAVING COUNT(parent) > 2
)
I believe this is enough to find the parent id
SELECT parent
FROM tablename
GROUP BY parent
HAVING Count(parent) > 2