简体   繁体   中英

SQL retrieving tree structure query

I have 2 tables

Products table:

ID     ProductName    Category
0      T-Shirt        15
1      Aqua De Gio    12
2      Jacket         15
3      Hot Water      13

Categories table:

categoryID catagoryName       highercategoryID
8          Fragnance          0
99         Clothing           0
15         Armani Clothing    99
12         Armani Fragnance   8
102        Davidoff Fragnance 8

Expected result

ID     ProductName    Category  CategoryTree 
0      T-Shirt        15        Clothing > Armani Cloting
1      Aqua De Gio    12        Fragnance > Armani Fragnance
2      Jacket         15        Clothing > Armani Cloting
3      Hot Water      13        Fragnance > Davidoff Fragnance

For example take the T-Shirt from the products table

  1. its category is 15.
  2. go for the categories table and see where categoryID=15
  3. look at the highercategoryID if its = 0 stop, if not then take its value 99
  4. look for 99 in the categoryID column, the higher category now is 0 so stop. based on the above I need to get "Clothing > Armani Clothing".

I am new to SQL queries and here is my first try

select  
    x.*,
    x.p1 + isnull((' > ' + x.c1), '') + isnull((' > ' + x.c2), '') as CategoryTree 
from 
    (select 
         RP.categoryid as catid,
         RP.catagoryName    as p1,
         R1.catagoryName    as c1,
         R2.catagoryName    as c2
     from 
         categories as RP
     left outer join 
         categories as R1 on R1.highercategoryid = RP.categoryid
     left outer join 
         categories as R2 on R2.highercategoryid = R1.categoryid 
     left outer join 
         categories as R3 on R3.highercategoryid = R2.categoryid 
     where 
         RP.highercategoryid != 0 ) x 

I am not sure how to stop the joining when I find the 0 value in the higher category, and how to join the products on their categories, and is there a dynamic way without using a lot of joins?

Here it goes:

With CTE (CatID, CatName, HigherCatID) AS
(
  SELECT categoryID, CAST(catagoryName AS VARCHAR(1000)), highercategoryID
  FROM CATEGORIES
  UNION ALL
  SELECT C.categoryID, CAST(CTE.CatName + ' > ' + C.catagoryName AS VARCHAR(1000)), CTE.HigherCatID
  FROM CATEGORIES C
  INNER JOIN CTE ON C.HigherCategoryID = CTE.CatID
)
SELECT P.ID, P.ProductName, Cte.CatID, CTE.CatName
FROM CTE INNER JOIN PRODUCTS P
ON (CatID = P.Category)
WHERE CTE.HigherCatID=0 

you got a SQLFiddle Here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM