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
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 looked at similar questions, but I can't seem to wrap my head around how the answers work in order to apply them to my case.
I have sets of articles (set_table)
ID SET ID ART
1 1
1 4
2 1
2 4
3 2
1 3
Those articles have a table with their parent ID. (article_table)
ID ART ID PARENT
1 1
2 3
3 2
4 1
Then those parents have a condition they have to meet, but it could be multiple (parent_table):
PARENT ID GROUP ID
1 6
2 15
3 12
Meaning, I have to select all sets whose articles (all of them) are in GROUP 6, then the result should be ID SET: 2. Or I could need to select all sets whose articles (all of them) are in GROUPS 6 and 15, then the result should be ID SET: 1. Or I could need to select all sets whose articles (all of them) are in GROUPS 6, 12; then the result should be NULL.
I have tried:
SELECT parent_id
FROM parent_table
WHERE group_id IN (6,15)
GROUP BY parent_id
HAVING COUNT(DISTINCT group_id) = 2; -- Number of group ids
Which is cool, but I don't manage to filter the sets correctly, my attempts in selecting the set are not working.
The query below is not so painful once you start writing it. Just join together the three tables, and then use conditional aggregation to count the number of entries in an ID_SET which have the desired groups.
The following query finds the ID_SET values which have groups of either 6 or 12. Note that this will return an empty result set for the sample data you gave in your original question. The DISTINCT subquery is needed to remove duplicates group values which would otherwise throw off the conditional aggregation.
SELECT t.ID_SET,
SUM(CASE WHEN t.GROUP_ID IN (6, 12) THEN 1 ELSE 0 END) AS groupCount
FROM
(
SELECT DISTINCT s.ID_SET, p.GROUP_ID
FROM set_table s
INNER JOIN article_table a
ON s.ID_ART = a.ID_ART
INNER JOIN parent_table p
ON a.ID_PARENT = p.PARENT_ID
) t
GROUP BY t.ID_SET
HAVING groupCount = 2 -- change 2 to however many group values you want to match
Use the below query
select ID ART
from articles a
join Parent1 p1 on a.ID ART = p1.ID ART
join Parent2 p2 on p1.ID PARENT = p2.PARENT ID AND p2.GROUP ID in (6,12)
I currently have the following SQL query wich retrieves a record from a table and also it's parents and grandparent. The only issue I have is that it's returned as a single record. I would like it return as multiple rows, as it's stored in the database.
Current structure:
comment_id | parent_comment_id
1 3
2 7
3 5
7 11
SQL:
SELECT p3.comment_id as `Grandparent`, p2.comment_id as `Parent`, p1.comment_id as `Child`
FROM comments p1
LEFT JOIN comments p2 on p1.comment_id = p2.parent_comment_id
LEFT JOIN comments p3 on p2.parent_comment_id = p3.comment_id
WHERE p1.comment_id = 1
Current Output (single row):
Grandparent | Parent | Child
5 3 1
Desired Output (separate rows):
comment_id
5
3
1
I am editing some existing mysql code, I do not have the option to convert everything to mysqli or pdo at the moment.
try this:
select comment_id from cm where comment_id = 1
union
select parent_comment_id from cm where comment_id =1
union
select g.parent_comment_id from cm g
join cm p
on p.parent_comment_id = g.comment_id
where p.comment_id = 1;
please verify the logic and make sure it gives you the correct result.
Demo: SQLFiddle
I want the value for users with the right ref and also users with extra value 1.
I have the following query but its not giving unique rows ,its giving duplicate rows.How do I resolve that ? I really appreciate any help.
basically its repeating values of ref.id if tab2.user=1 which repeats 4,6 row again in the final query I dont want both but only one as ref.id=0 does not exist but I want extra=1.
SELECT * FROM
tab1,tab2
WHERE tab1.ref=tab2.ref
AND tab1.to_users = 1
OR users.extra=1;
Tab1
sno users ref extra
1 1 4 1
2 2 5 0
3 3 0 1
4 1 0 1
5 2 5 0
6 3 0 1
Tab2
ref ad user
4 A 1
5 B 2
6 C 1
After your last comment:
SELECT sno, users, tab1.ref, extra, max(ad) as ad
FROM
tab1,tab2
WHERE tab1.ref=tab2.ref
AND tab1.users = 1
OR tab1.extra=1
group by sno, users, ref, extra;
This will max the ad column (alternatively you can use min - all depends on your requirements)
example: http://sqlfiddle.com/#!2/1837e/25
You will probably need to use join
SELECT * FROM
tab1 LEFT JOIN tab2 ON tab1.ref=tab2.ref
WHERE tab1.users = 1 OR tab1.extra=1;
GROUP BY tab1.users
edit: added group by
GROUP BY users, give below syntax a try
SELECT * FROM
tab1,tab2
WHERE tab1.ref=tab2.ref AND (tab1.users = 1 OR tab1.extra=1)
GROUP BY users;
Its more common to also join tables than they way you write your syntax,
SELECT * FROM
tab1 JOIN tab2 ON tab1.ref=tab2.ref AND (tab1.users = 1 OR tab1.extra=1)
GROUP BY users;
You should use parenthesis to change the priority of And and OR :
SELECT * FROM
tab1,tab2
WHERE tab1.ref=tab2.ref
AND (tab1.to_users = 1
OR users.extra=1);
otherwise it will be run like this :
SELECT * FROM
tab1,tab2
WHERE (tab1.ref=tab2.ref
AND tab1.to_users = 1 )
OR users.extra=1;
UPDFATE:
I thought you were looking for rows with same reference where to_users is one or extra is one. Then as Krzysztof Rosiński says LEFT JOIN should do the trick but there's no need to use GROUP BY and perhaps you should use DISTINCT something like this :
SELECT DISTINCT * FROM
tab1 LEFT JOIN tab2 ON tab1.ref=tab2.ref
WHERE tab1.users = 1 OR tab1.extra=1;
I'm creating an e-commerce site where I have the category_id in the URL and based on the category_id I'll query all the children and grandchild (if found) so I can display products only related to that category_id. This query is really cool because it doesn't care about how many parent's it has ... it just looks for all the parents until it doesn't find any more.
The problem I'm having is my query will only get parent and grand parents (if found), but I cannot seem out how to make this query get all children rows or grandchildren if found. This query was pulled from here, so I did not write the query and it's hard for me to make the correct changes ... I tried all day yesterday.
Edit
This query will also NOT get ALL the related children and grandchildren (if found). Where I want ALL children and grand children (if found).
Edit
Here's the SQL Fiddle where my data can be found.
SELECT T2.category_id, T2.category_name
FROM (SELECT #r AS _id, (SELECT #r := parent
FROM categories
WHERE category_id = _id) AS parent
FROM (SELECT #r := 182)vars, categories h
WHERE #r <> 0) T1
JOIN categories T2
ON T1._id = T2.category_id
ORDER BY category_id ASC
Here's my table schema:
category_id | category_name | parent
There is an alternate way to accomplish this, but it requires a second hierarchy table.
The additional table contains one row per parent-direction relationship, as in:
category_id category_name parent
1 cat1 1
2 cat2 1
3 cat3 1
4 cat4 2
5 cat5 3
6 cat6 5
category_id ancestor
1 1
2 1
3 1
4 1
4 2
5 1
5 3
6 1
6 3
6 5
This table can be maintained by your code or by a trigger. It makes selecting an entire hierarchy trivial and very fast, but adds some maintenance (addition/deletion) overhead, so you'll need to consider the long-term costs vs overhead.
If you know in advance the maximum possible amount of depth like #rambocoder indicated…
SELECT
p.`category_id`,p.`category_name` AS 'parent',
c.`category_name` AS 'child',
gc.`category_name` AS 'grandchild'
FROM (SELECT * FROM `categories` WHERE `parent` IS NULL) p
INNER JOIN `categories` c
ON c.`parent`=p.`category_id`
INNER JOIN `categories` gc
ON gc.`category_id`=c.`category_id`
WHERE p.`category_id`=120
ORDER BY c.`category_id`, gc.`category_id`
Otherwise if you're not sure how many levels deep the result might get, then you will need to write a stored procedure.