Nested queries (dependent queries) - mysql

I need to store a family (i.e. some childs of a parent. Those childs have their own childs and so on..)
So, I created a table family that has following structure
id child child_id parent_id
When I save a child, I store a parent_id along with it.
Now,
when I want to fetch all childs of given parent, I can easily do.
select child_id from family where parent_id = <given parent id>
But,
now I want to fetch the complete family (all descendants of a given parent)
i.e.
I want to fetch all childs which have a given parent_id + all childs that are childs of fetched childs in first query and so on.
Can somebody help me ?
I also, thing there could be better way to store the data initially, so I can fetch it later. Can somebody point out a better way ?

You can write a query that will fetch a child and all of its dependants, but first you would need to re-design your table structure and a enforce a protocol when adding new children to make the query work all the time.
Take a look at this very useful article describing and explaining this method

use sub query
select GC.grandchildren,children from children C inner join grandchildren GC
on C.childid=GC.id and
C.childid in
(select child_id from family
where parent_id = <given parent id>)

Regarding your table design, I think your child_id column is redundant, you can just build the hierarchy by setting which is the parent_id of a certain node, and leave the parent_id empty for the root nodes.
Regarding the query for traversing all childs, you can use an approach like the one proposed here (http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/), but it wll mean you will need to follow some conventions in your ids and store a 'path' with each node.
(which will complicate things if you need to insert something in the middle ot the tree)
Other database brands have clauses for this problem (for Oracle, you have the STARTS WITH ... CONNECT BY clause), but none of them are ANSI.
Hope it helps

Related

What is the most efficient way to delete hierarchies in mysql

I am using a modified version of adjacency list to store hierarchical data. So a tree of this sort is created.
The same is represented in mysql schema in this way :
What is the best way to delete a node in between say C so that the children F, G are now children of A ?
At application level you'll need to list down the childs of the node to be deleted and assign those childs' levels columns to parent node.
You can otherwise create a trigger on delete of node from the table which will do the above task.
If you would have structured your table correctly your all tasks would have been much easier.
table should have been just a parent child relation where immediate parent is saved.
Id Name ParentId
1 A NULL
2 B 1
3 D 2
levels can be determined by the no. of times recursion is done.
you can even do that now by adding the parent column and writing a script which would add the last levels available in the column.
So in this case, deletion would be simply
1. get list of childs - where parentid=nodeid.
2. updating their parent column with nodeids' parentid.
instead of updating and calculating all 3 level columns.

Merging 2 tables horizontally

I have 2 tables Parents and kids in a MySQL DB, I would like to merge these 2 tables
I would like to know how to query both the tables so I get the following result (query), is this possible? if so, how could I do this?
Simple LEFT JOIN does the job
SELECT *
FROM Parents
LEFT JOIN kids
ON Kids.parents = parent.id
This should work(sort of):
SELECT *
FROM Parents
JOIN kids
ON parents.id = kids.parent
That will give you a result where each Child is on its own line though parents of multiple children will be repeated. This is probably a slightly nicer way of doing it. Your way is possible but it is a pain. You can find the answer on here, it is something that is asked fairly often.
Can I also suggest changing your structure?
I would suggest making a single name attribute for parent instead of father and mother and giving each represented person their own DB entry. Then give each kid a "motherId" and a "fatherId" instead of the combined "parents" attribute. Maybe also try to get into the habit of using "attribueId" attributes to clarify your relationships. This should give you a cleaner schema and be much easier to work with. As it is you have a coupled "parents" entity which needlessly links the father and mother or forces a null value to appear. If instead you have a "parent" entity you have much more freedom. It changes your logical 1 to 1 into a 1 to many.

Accessing Nested Parent Properties

I believe this is a relatively basic feature of SQL, but unfortunately I'm not managing to think of exactly how it's done, or what it would be called.
Basically, in my current database, we have Areas, which are parts of Districts, which are parts of Zones, which make up a Region.
Along this chain, each parent only has the ID of the next parent, however, I would like to generate a table with all Areas, where every Area has columns for the ID of the District, Zone, and Region of which it's part of. So how would I write this query?
Oracle offers hierarchical querying, where you can say something like
SELECT parent, child, LEVEL
FROM table
START WITH parent IS NULL
CONNECT BY PRIOR child = parent
The START WITH condition identifies the root of the hierarchy, and the CONNECT BY PRIOR clause identifies how to traverse the hierarchy.
MySQL doesn't have this capability, unfortunately.
Well, Laurence(in the comments) responded correctly, I've been out of the SQL game for a bit too long it seems.
So the simple answer would be:
SELECT child.id as ChildID, parent.id as ParentID, grandparent.id as GrandparentID
FROM child JOIN parent JOIN grandparent
WHERE child.parentID = parent.id AND parent.parentID = grandparent.id
Thanks to all who didn't hardcore downvote this terrible question.

selecting element which refer to other elements in the same table

I am trying to build a very simple CMS. For that I have create a table called categories. As the name suggests it will be the categories for my articles in the CMS.
My table looks like follows with the sample data:
As you can see, a category node has a parent node. now, How can I write a query which selects all the parent nodes of a particular node. Example, if I choose, the node Important, how can I write a query which will return me the following nodes: News, Users, General
I hope I was clear enough
I can't say that I really love this method, but the following appears to work in MySQL:
select t.id, t.parent, #parent := parent
from (select #parent := 7) const join
t
on t.id = #parent;
You can see it in this SQL Fiddle.
I don't believe this is guaranteed to work, but it seems to work in practice. If you need to store hierarchical data, you should really change the data structure or switch to a database that supports recursive queries (Postgres, SQL Server, and Oracle, for instance).

What table structure to use for nested data?

Okay, so I'm working on a project with hierarchical data that I'm using for a book-writing app like so:
top-level parent (Act) - contains Act name, position (first Act), description, and text (intro text)
mid-level parent / child (Chapter) - contains Chapter name, position (first Chapter), description, and text (intro text)
bottom-level (Section) - contains Section name, position (first Section), description, and text (actual content text)
Now, I want to have a variable number of levels (for example include sub-sections that will have the full text), but I'm not entirely sure how to create a table like this efficiently. My initial thought was to have them connected by parentId with top-level having a null for parentId.
For example, if I want to call up a top-level parent in the first position, it's not a big deal. Right now, I can search for nulled parent fields and for a position of 1.
To call up a "chapter" (mid-level), I do the same thing but get the id of the result and use it as a parentid.
The problem is for section, I'd have to have several sub-queries to get to the final result. If I want to ahve variable number of levels, I'd require numerous sub-queries which will be a performance hit.
I saw a similar question but did not really understand the answer or how i could use it.
I already considered some kind of taxonomy table or carrying over all parent ids into the children (ie. a section will have both chapter and act ids listed under parentid) but I'm not set on it. Feedbooks.com uses a similar hierarchy when submitting a book but they don't store data in a database, they just take an input and convert it to an output (a pdf, epub or whatever).
Oh and, I plan on building this in MySQL.
Ideas?
EDIT
An easier way of imagining this scenario is with a family. Let's say you have 3 grandfathers (Bill, Bernard, Boe), who have 5 children between them (John, Joey, Josh, Jeremy, Jackson), who, in turn have all 2 children of their own (examples: Donald, Duey, Donnie). And let's say the database does not store THAT relationship but rather the relationship of what child is staying where and we don't care about the biology here.
So let's say Donnie started out living with John who lives with Bill. Donnie is John's first child and John is Bill's second child. How do you query Bill's first grandchild of the second son?
Let's say they move around and now Donald is staying with John instead. Donald is John's second child (the first child position was filled with someone else) and John is still Bill's second child. How do you query Bill's second grandchild of the second son?
What if John moves with all his children to Boe's house. Boe is the second grandfather. How do you query this information now? How would you store this type of information?
What if you throw great-grandchildren into the mix now?
This is a good example to use closure tables, as on the answer you are referencing. You may want to take a look here and here.
Quoting from the first link:
The Closure Table is a design for representing trees in a relational
database by storing all the paths between tree nodes.