2010-12-03 63 views
3

我有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 Subcategory lvl_1';

3,2,'Books Subcategory lvl_2';

4,3,'Books Subcategory lvl_3';

ProductToCategoryLink:

1,4;

2,2;

問題:如何獲取每個產品所屬的所有父級和子級類別?

所以,我需要得到的東西是這樣的:


的productID,產品名稱,的categoryID,類別名稱

1, 'Book_1',1, '圖書';

1,'Book_1',2,'Books Subcategory lvl_1';

1,'Book_1',3,'Books Subcategory lvl_2';

1,'Book_1',4,'Books Subcategory lvl_3';

2,'Book_2',1,'Books';

2,'Book_2',2,'Books Subcategory lvl_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 
3

最簡單的方法是通過公共表格表達式。 >Link<

使用直接鏈接作爲錨點,然後展開兩次:首先展開找到的錨點的父母,然後用第二個聯合展開子類。

+0

非常酷的,從來沒有聽說過的CTE之前。這將會在一些舊的項目中派上用場:) – CodeMonkey1313 2010-12-03 12:13:37

相關問題