Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show recursive parentID in a single column in SQL

Here is the example structure of the table:

ID    Name     ParentID
-----------------------
1     Ancestor      NULL
2     GrandFather   1
3     GrandMother   1
4     Child         3

I'm trying to write a query that would return

ID     Name        Family
----------------------------
 1     Ancestor 
 2     GrandFather Ancestor
 3     GrandMother Ancestor
 4     Child       Ancestor^GrandMother

The tricky part is that I want to show the family of all rows and in a top-down order.

If anyone can point me in the right direction, it would be appreciated :)

EDIT :: This is the real query, but it follows the same idea. it returns an error on line : marketparent.family + '^'+ t2.marketGroupName because it cant find marketparent

WITH marketparent ( marketGroupID,parentGroupID, marketGroupName,family)
AS
(
SELECT marketGroupID,
       parentGroupID,
       marketGroupName,
       '' as family 
 FROM EVE.dbo.invMarketGroups
 WHERE parentGroupID IS NULL
UNION ALL

    SELECT t2.parentGroupID,
     t2.marketGroupID,
     t2.marketGroupName,
     marketparent.family + '^'+ t2.marketGroupName
     FROM EVE.dbo.invMarketGroups as t2
     INNER JOIN marketparent as mp
     ON mp.marketGroupID = t2.parentGroupID
)

-- Statement using the CTE

SELECT TOP 10 *
FROM marketparent;
like image 401
darthun08 Avatar asked Apr 16 '12 15:04

darthun08


People also ask

How do you create a recursive view in SQL?

First, specify the name of the view that you want to create in the CREATE RECURSIVE VIEW clause. You can add an optional schema-qualified to the name of the view. Second, add the SELECT statement to query data from base tables. The SELECT statement references the view_name to make the view recursive.

How do I get all parent children in SQL?

parent = c. child ) SELECT distinct parent, child , level FROM cte order by level, parent; This will give you all descendants and the level.

How do you do recursive CTE?

Recursive CTE Syntax Again, at the beginning of your CTE is the WITH clause. However, if you want your CTE to be recursive, then after WITH you write the RECURSIVE keyword. Then it's business as usual: AS is followed by the parentheses with the CTE query definition.


1 Answers

You did not specify your DBMS, so I'm assuming PostgreSQL

WITH RECURSIVE fam_tree (id, name, parent, family) as 
(
  SELECT id, 
         name, 
         parentid, 
         ''::text as family
  FROM the_unknown_table
  WHERE parent IS NULL

  UNION ALL

  SELECT t2.id, 
         t2.name, 
         t2.parentid, 
         fam_tree.family || '^' || t2.name
  FROM the_unknown_table t2 
     INNER JOIN fam_tree ON fam_tree.id = t2.parentid
)
SELECT *
FROM fam_tree;

This is standard SQL (except for the ::text typecast) that should work with very few changes on most modern DBMS.

Edit:

For SQL Server you would need to replace the standard concatention character with Microsoft's non-standar + (and you need to remove the recursive keyword which is required by the standard but for some strange reason rejected by SQL Server)

WITH fam_tree (id, name, parent, family) as 
(
  SELECT id, 
         name, 
         parentid, 
         '' as family
  FROM the_unknown_table
  WHERE parent IS NULL

  UNION ALL

  SELECT t2.id, 
         t2.name, 
         t2.parentid, 
         fam_tree.family + '^' + t2.name
  FROM the_unknown_table t2 
     INNER JOIN fam_tree ON fam_tree.id = t2.parentid
)
SELECT *
FROM fam_tree;
like image 182
a_horse_with_no_name Avatar answered Oct 18 '22 17:10

a_horse_with_no_name