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
Related
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 = ' '
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;
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);
I have the following MySQL table:
id rid
----- ------
1 2
2 1
2 3
3 2
1 3
3 1
I want to change this so only one row per relation exists.
e.g:
id rid
----- ------
1 2
2 3
1 3
If you always have pairs (as in your example):
delete from table
where id > rid;
This keeps the record where id is smaller.
If there is the possibility that no all pairs exist, then:
delete t
from table t left outer join
(select least(id, rid) as lid, greatest(id, rid) as gid, count(*) as cnt
from table t2
group by least(id, rid), greatest(id, rid)
) t2
on least(t.id, t.rid) = t2.lid and greatest(t.id, t.rid) = gid
where id < rid or t2.cnt = 1;
EDIT (explanation):
How does the second query work? Let me be honest, what I want to write is this:
delete t from table t
where id < rid or
(id > rid and
not exists (select 1 from table t2 where t2.id = t.rid and t2.rid = t.id
);
That is, I want to keep all records where id < rid. But then, I also want to keep all singleton records where rid > id. I don't think MySQL allows the syntax with the where clause.
Instead, the query in the answer counts the number of times that a pair exists, by looking at the smallest value and the largest value. For the data in the question, the result of the subquery is:
id rid cnt
1 2 2
2 3 2
1 3 2
So, all of these would use the id < rid to select the row. If you had one more row, say 4, 1. It would look like:
lid gid cnt
1 2 2
2 3 2
1 3 2
1 4 1
In this case, the first three would take the row with id < rid. But the new row would also be selected because the cnt is 1.
If you had duplicates in the table and a primary key, there would be a slight variation on the query that would do the same thing.
I have a MySQL table of following structure.
**Table elements :**
element_id element_name parent_id
1 UIG 0
2 CAM 1
3 IHG 1
4 USR 1
5 DBL 1
6 APD 1
7 RTM 1
8 OCR 2
9 IRT 3
10 ICR 3
11 OCR 2
12 USH 1
13 AML 1
I need to find child elements of a given element.
I made the following query :
SELECT parent_id,GROUP_CONCAT(element_id)
FROM elements
WHERE parent_id='1'
GROUP BY parent_id
which returns,
+-----------+--------------------------+
| parent_id | GROUP_CONCAT(element_id) |
+-----------+--------------------------+
| 1 | 2,3,4,5,6,7,12,13 |
+-----------+--------------------------+
1 row in set (0.00 sec)
While I need also need the childs of element 2 and 3, which should result into
+-----------+------------------------------------+
| parent_id | GROUP_CONCAT(element_id) |
+-----------+------------------------------------+
| 1 | 2,3,4,5,6,7,8,9,10,11,12,13 |
+-----------+------------------------------------+
1 row in set (0.00 sec)
How do I achieve this without procedures and just a query?
You just need to use the in operator on a subquery.
select group_concat(element_id)
from chpr
where parent_id in (
select group_concat(element_id)
from chpr
where parent_id = 1
group by parent_id)
;
** AS per OP's comment the levels are definitely a concern**
However based on the initial sample data and request, here is the SQLFIDDLE DEMO that provides the results as per the question's expected output.
The only change is that one needs to group by both element_id and parent_id the innner most first subquery.
Not a very elegant query at all:
select 1 as parent_id, group_concat(x.element_id)
from (
(select element_id
from chpr
where parent_id in
(select element_id
from chpr
where parent_id = 1
group by element_id, parent_id
))
union all
(select element_id
from chpr
where parent_id = 1
group by element_id, parent_id
)) x
;
Results:
PARENT_ID GROUP_CONCAT(X.ELEMENT_ID)
1 8,9,10,11,2,3,4,5,6,7,12,13
Use an IN () predicate...
SELECT '1' As Parent_Id,GROUP_CONCAT(element_id)
FROM elements
WHERE Parent_Id IN ('1','2','3')
GROUP BY '1';
Some database require the GROUP BY in this scenario others don't but it's fairly good practice to include it even if it is not needed.
Incidentally, I suspect Parent_Id is a numeric of some sort in which case it should really read...
SELECT 1 As Parent_Id,GROUP_CONCAT(element_id)
FROM elements
WHERE Parent_Id IN (1,2,3)
GROUP BY 1;
You could actually exclude the 1 As Parent_Id and GROUP BY 1 completely.
If you can only specify one value use a sub-query...
SELECT GROUP_CONCAT(element_id)
FROM Elements
WHERE Parent_Id IN (SELECT Element_Id
FROM Elements
WHERE Parent_Id = 1)
Take a look at my this question
Finding all parents in mysql table with single query (Recursive Query)
And here is the source for this kind of work.
http://explainextended.com/2009/07/20/hierarchical-data-in-mysql-parents-and-children-in-one-query/