SQL:使用公用表表达式递归获取父记录

标签 sql sql-server sql-server-2005 common-table-expression

假设您必须遵循以下表格,其中销售由产品组成,并且产品可以放在多个类别中。其中类别具有如下层次结构:

Man
 Shoes
  Sport
  Casual
 Watches
Women
 Shoes
  Sport
  Casual
 Watches
表格:
Sale:
    id name 
    1  Sale1

Product:
    id saleidfk name 
    1  1        a
    2  1        b
    3  1        c
    4  1        d
    5  1        e

ProductCategory :
    productid categoryid 
    1         3
    2         3           
    3         4
    4         5
    5         10     

Category:
    id ParentCategoryIdFk name 
    1  null               Men
    2  1                  Shoes
    3  2                  Sport
    4  2                  Casual
    5  1                  Watches
    6  null               Women
    7  6                  Shoes
    8  7                  Sport
    9  7                  Casual
    10 6                 Watches
题:
现在在我的网站上,我想创建一个控件,其中只显示某个销售的类别,并且类别中填充了销售的产品。我也想要
包括类别的层次结构。因此,如果我们有一个叶节点,则递归地上升到顶部节点。
所以对于 sale1 我应该有一个查询结果如下:
Men
  Shoes
    Sport
    Casual
  Watches
Women
  Watches

最佳答案

尝试这样的事情 - 获得类别的分层列表的基本 CTE 类似于:

WITH Categories AS
(
    SELECT Cat.ID, Cat.NAME, Cat.ParentCategoryID, CAST('none' AS VARCHAR(50)) AS 'ParentCategory', 1 AS 'Level'
    FROM dbo.MBCategory Cat
    WHERE Cat.ParentCategoryID IS NULL

    UNION ALL

    SELECT Cat.ID, Cat.NAME, Cat.ParentCategoryID, c2.NAME AS 'ParentCategory', LEVEL + 1
    FROM dbo.MBCategory CAT
    INNER JOIN Categories c2 ON cat.ParentCategoryID = c2.ID
)
SELECT * FROM Categories

现在你需要做的是将你的其他表加入这个 CTE,最终得到以下查询:
WITH Categories AS
(
    SELECT Cat.ID, Cat.NAME, Cat.ParentCategoryID, CAST('none' AS VARCHAR(50)) AS 'ParentCategory', 1 AS 'Level'
    FROM dbo.MBCategory Cat
    WHERE Cat.ParentCategoryID IS NULL

    UNION ALL

    SELECT Cat.ID, Cat.NAME, Cat.ParentCategoryID, c2.NAME AS 'ParentCategory', LEVEL + 1
    FROM dbo.MBCategory CAT
    INNER JOIN Categories c2 ON cat.ParentCategoryID = c2.ID
)
SELECT DISTINCT s.*, c.*
FROM dbo.Sale s
INNER JOIN dbo.Product p ON p.SaleID = s.ID
INNER JOIN dbo.ProductCategory pc ON p.ID = pc.ProductID
INNER JOIN Categories c ON pc.CategoryID = c.ID
ORDER BY Level

这给了我一个类似的结果输出:
ID  Name   CatID  CatName  ParentCatID  ParentCatName Level
 1  Sale1    5    Watches      1            Men         2
 1  Sale1   10    Watches      6            Women       2 
 1  Sale1    3    Sport        2            Shoes       3
 1  Sale1    3    Sport        2            Shoes       3
 1  Sale1    4    Casual       2            Shoes       3

关于SQL:使用公用表表达式递归获取父记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2618102/

相关文章:

PHP/HTML - 表格无法正确显示

mysql - 如何从 mysql 多对多选择中将单个值分组为数组?

sql - 将数据合并到两个目标表中

sql-server - SQL Server 对行数的约束

sql-server-2005 - 从相对路径批量插入图像

sql-server-2005 - 在SQL 2005中从递归查询结果排序层次结构

SQL - 与同一列中的多个值进行比较?

sql - 如何在按时间顺序排序的单个表中加入成对的记录(使用 MySQL)

c# - 检查行是否已在 SQL 中更新的最佳方法

sql - 如何验证格式为 MMM/DD/YY 或 MMM/DD/YYYY 的日期字段?