Reputation: 20178
I've a table where products are categorised based on hierarchical relationship like a tree structure. I'm having to select a category and all subcategories at any level. See the picture below:
e.g. i want an sql statement that when i query passing the id=11, it returns me (19,20,21,22,23,24,25,26)
Upvotes: 7
Views: 1635
Reputation: 36
This is messy, and you'll have to do n unions, where n is how deep your hierarchy is, but it should work:
SELECT * FROM `Products` WHERE parentId IN (
SELECT id FROM `Products` WHERE parentId = 11)
UNION
SELECT * FROM `Products` WHERE parentId IN (
SELECT id FROM `Products` WHERE parentId IN (
SELECT id FROM `Products` WHERE parentId = 11))
UNION
SELECT * FROM `Products` WHERE parentId IN (
SELECT id FROM `Products` WHERE parentId IN (
SELECT id FROM `Products` WHERE parentId IN (
SELECT id FROM `Products` WHERE parentId = 11)))
Upvotes: 0
Reputation: 13549
SELECT * FROM `Products`
WHERE parentId IN (
SELECT id FROM `Products`
WHERE parentId = 11)
NOTE: This won't work if your hierarchy is deeper than 2 levels.
Upvotes: 1
Reputation: 839074
There are several different ways to store heirarchical data in MySQL. Check out Bill Karwin's presentation that demonstrates four options.
You are using the adjacency list model for storing heirarchical data, but unfortunately this is the hardest model you could choose for querying subtrees.
Your options are:
Upvotes: 11
Reputation: 9762
Could you change your data-structure a little to include a computed linage column. There's a great article which shows you the generic concept (ignore the database type).
Basically your computed linage column should contain the list of parents in it for example
Item 26 would contain \11\
If you had a subitem you could have
\11\subitem\
Then you can simply do a like check on your linage table, its much faster than a iterative search, and you could do create it using a stored proc or triggers.
Node ParentNode EmployeeID Depth Lineage
100 NULL 1001 0 /
101 100 1002 1 /100/
102 101 1003 2 /100/101/
103 102 1004 3 /100/101/102/
104 102 1005 3 /100/101/102/
105 102 1006 3 /100/101/102/
Upvotes: 1