如何获取每个产品所属的所有父类和子类?

时间:2010-12-03 10:57:21

标签: sql sql-server sql-server-2005 sql-server-2008

我有3张桌子:

CREATE TABLE [dbo].[ProductCategory](
 [categoryID] [int] IDENTITY(1,1) NOT NULL,
 [categoryParentID] [int] NULL,
 [categoryName] [nvarchar](200) NOT NULL
)

CREATE TABLE [dbo].[Product]
(
 [productID] [bigint] IDENTITY(1,1) NOT NULL,
 [productName] [nvarchar(100)] NOT NULL,
 .
 .
)

CREATE TABLE [dbo].[ProductToCategoryLink]
(
 [productID] [bigint] NOT NULL,
 [categoryID] [int] NOT NULL
)

示例数据示例:

产品:

1,'Book_1';

2,'Book_2';

产品分类:

1,NULL,'书籍';

2,1,'Books子类别lvl_1';

3,2,'Books子类别lvl_2';

4,3,'Books子类别lvl_3';

ProductToCategoryLink:

1,4;

2,2;

问题:如何获取每个产品所属的所有父母和子女类别?

所以,我需要得到这样的东西:


productID,productName,categoryID,categoryName

1,'Book_1',1,'书籍';

1,'Book_1',2,'图书子类别lvl_1';

1,'Book_1',3,'Books子类别lvl_2';

1,'Book_1',4,'Books子类别lvl_3';

2,'Book_2',1,'书籍';

2,'Book_2',2,'Books Subcategory lvl_1';

2 个答案:

答案 0 :(得分:3)

最简单的方法是通过公用表表达式。 >Link<

使用直接链接作为锚点,然后展开两次:首先展开找到的锚点的父项,然后使用第二个联合项展开所有锚点。

答案 1 :(得分:1)

如果详细说明,本帖子底部展示的SQL查询应该可以解决问题。

关键特性是层次结构表表达式的递归定义。第一个SELECT检索所有产品类别链接及其名称和类别父ID。这是递归的基本情况。第二个SELECT查找上一步中找到的所有行的所有类别父行。特别注意第二个SELECT再次加入层次结构表达式,使查询递归。 SQL Server将重复评估第二个SELECT,直到找不到新记录。第三个SELECT语句只返回结果。

正如您所料,如果类别父链中存在循环,那将是一件坏事。 SQL Server限制在放弃查询之前它将递归的次数。默认限制为100,除非类别层次结构非常深,否则这可能就足够了。如有必要,您可以使用MAXRECURSION查询选项将其提升至32767。

这是SQL查询:

WITH
  hierarchy AS (
    SELECT
      prod.productId
    , prod.productName
    , cat.categoryId
    , cat.categoryParentId
    , cat.categoryName
    FROM dbo.ProductToCategoryLink AS link
    INNER JOIN dbo.Product AS prod
      ON prod.productId = link.productId
    INNER JOIN dbo.ProductCategory AS cat
      ON cat.categoryId = link.categoryId
    UNION ALL
    SELECT
      child.productId
    , child.productName
    , parent.categoryId
    , parent.categoryParentId
    , parent.categoryName
    FROM hierarchy AS child
    INNER JOIN dbo.ProductCategory AS parent
      ON parent.categoryId = child.categoryParentId
  )
SELECT
  productId
, productName
, categoryId
, categoryName
FROM hierarchy
ORDER BY
  productId
, categoryId