Get root element and all descendants MS SQL - sql

I should get root element with all descendants from that structure:
rootA
rootB
child1
rootC
child2
chold3
rootD
child4
RESULT:
Root| Child
rootA child1
rootA child2
rootA child3
rootD child4
I understand, that firstly I should get root elements without parents:
SELECT DISTINCT
rootId,
childId
FROM
root
WHERE rootId IS NULL
But I dont know the next step.
Do you have some variants?
Thanks!

This is done with a Common Table Expression (CTE):
;WITH cte_hierarchy AS (
-- get all roots
SELECT DISTINCT
rootId, childId
FROM
root
WHERE rootId IS NULL
UNION ALL
-- this is the recursive part
-- get all children for all roots, including children of children, etc.
SELECT
child.rootId, child.childId
FROM root child
JOIN cte_hierarchy parent ON parent.childid=child.rootid
)
SELECT * FROM cte_hierarchy;

Related

Multi-level hierarchy data display in SQL Server Management Studio

I want to fetch a multi-level hierarchy in a sequential manner. I have a table BOMHierarchy in which I have this sample data:
Parent
Child
Parent1
Child1
Parent1
child2
Child1
Child3
Child1
Child4
Child3
Child5
Child3
Child6
I want to show the above data like below in proper hierarchical manner:
Parent
Child
Parent1
Child1
Child1
Child3
Child3
Child5
Child3
Child6
Child1
Child4
Parent1
Child2
I am stuck at fetching this sequential data according to the hierarchy. Can anyone please provide a solution?
I have tried using a CTE and while loop but I'm not getting the required result.
Looks like a classic problem of how to recursively scan a tree. In SQL is simple, what you just need is to create the right ORDER BY.
Try something like this
DECLARE #BOM table (Parent varchar(20), Child varchar(20))
INSERT INTO #BOM(Parent, Child)
VALUES ('Parent1', 'Child1'),
('Parent1', 'Child2'),
('Child1', 'Child3'), ('Child1', 'Child4'),
('Child3', 'Child5'), ('Child3', 'Child6')
-- find all possible combinations recursively
;WITH cte AS
(
SELECT
Parent, Child,
CONVERT(VARCHAR(MAX),Parent + '|' + Child) Chain
FROM
#BOM root
WHERE
NOT EXISTS (SELECT 1
FROM #BOM NotRoot
WHERE root.Parent = NotRoot.Child)
UNION ALL
SELECT
BOM.Parent, BOM.Child, cte.Chain + '|' + CONVERT(VARCHAR(MAX), BOM.Child) Chain
FROM
cte
INNER JOIN
#BOM BOM ON cte.Child = BOM.Parent
)
SELECT
Parent, Child
FROM
cte
ORDER BY
Chain

SQL how to get parent and its all children and children of children... etc

I have to see I am new to sql.
I have a table which looks like this:
child parent
-------------------
Nancy Bob
Oli Bob
Alice Oli
Mira Alice
Now I need sql statement which gives me parent -which is already known- and its children and children of its children... etc, given is parent name.
Example I need Family of Bob. The sql should return (Bob, Nancy, Oli, Alice, Mira)
I tried this: select child from myTable where parent='Bob' This gives me Nancy and Oli.
Any Idea?
You can use Oracle's hierarchial queries to get this along with the level of tree:
Demo
SELECT CHILD, LEVEL FROM TABLE1
START WITH PARENT = 'Bob'
connect by prior child = parent;
That’s a typical hierarchical query. One standard method uses a recursive with clause:
with cte (child, parent) as (
select child, parent from mytable where parent = 'Bob'
union all
select t.child, t.parent
from mytable t
inner join cte c on c.child = t.parent
)
select child from cte

Selecting child.id from parent table

In Parse you can select or include a key from a pointer. Select key Parent.child.id
Is it possible to do the same in SQL if you have child indexed to parent?
SELECT Parent.child.id
In SQL you do this:
Select * from parent, child where parent.id = child.id;

sql - How to return NULL row from left table for each parent even when child records exist

I have 2 tables with a parent-child relation. I'd like to return a row with NULL child values for parents that have children, in addition to the child records.
For example, for tables parent and child:
SELECT parent.parentid, childid
FROM parent
LEFT JOIN child
ON parent.parentid=child.parentid
For a parent parentA with children childA1, childA2, I'd like a result:
parentA, NULL
parentA, childA1
parentA, childA2
A normal LEFT JOIN will not return the first row. A UNION query works, but I'm wondering if there is a simpler/better query, using standard SQL for Oracle and SQL Server. My UNION query is:
SELECT parent.parentid, childid
FROM parent
INNER JOIN child ON parent.parentid=child.parentid
UNION
SELECT parent.parentid, NULL
FROM parent
I think your query is better written as:
SELECT p.parentid, childid
FROM parent p INNER JOIN
child c
ON p.parentid = c.parentid
UNION ALL
SELECT p.parentid, NULL
FROM parent p;
That is UNION ALL is better than UNION, because UNION has additional overhead for removing duplicate values. If you can have duplicates in parent, just use SELECT DISTINCT in the second query.
Also, you might want to add an ORDER BY to get results in order the question seems to specify:
ORDER BY parentid, (CASE WHEN child is NULL then 0 else 1 end), chile
An alternative way of doing it would be
SELECT parent.parentid,
childid
FROM parent
LEFT JOIN child
ON parent.parentid = child.parentid
GROUP BY GROUPING SETS( ( parent.parentid ), ( parent.parentid, childid ) )
HAVING (childid IS NOT NULL) OR GROUPING(childid) =1
ORDER BY parentid ASC,
GROUPING(childid) DESC
If you only want the row for parents with children you should use an inner join
SQL Fiddle - Oracle
SQL Fiddle - SQL Server

Parent - child sql query with in a single table

I've a table:
Id | Name | ParentID
I want to select records whose parentid not equal to zero, with parent record(parent record have parentid = 0, but some parent record don't have child record I want to skip them )
Try this:
SELECT child.Id,
child.Name,
child.ParentId,
parent.Name as ParentName
FROM your_table child
JOIN your_table parent ON child.ParentId = parent.id;
Check this one:
select * from child c,parent p where c.ID=P.ParentID and c.ParentID !=0