我有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';
答案 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