2012-04-26 116 views
1

我有兩個表,其中一個表是items容器,它包含與產品相關的所有數據。另一個表用於類別,其中數據是使用層次結構組織的。
查詢的目標是列出與所選類別下的類別匹配的項目。SQL Server INNER JOIN with hierarchid

實施例:

CatID: 3, Parent: Root, Name: Computers 
CatID: 4, Parent: 3, Name: Laptops 
CatID: 5, Parent: 3, Name: Monitors 
CatID: 6, Parent: 3, Name: Printers 
CatID: 7, Parent: 6, Name: Laser 
CatID: 8, Parent: 6, Name: Ink 
CatID: 9, Parent: 6, Name: Multifunction 
CatID: 10, Parent: 6, Name: Copier 

如果所選的CatID爲3,所有的計算機產品將被顯示,但是如果選擇了CatID 6,則只有打印機將顯示與CatID 7,8(物品, 9和10)

我對層次結構id相當陌生,對於如何處理這個查詢有點意見。

感謝所有人的貢獻。

卡洛斯

架構兩個表 的想法是加入mz_category到ic_item_cat,這樣的查詢可以列出所有項目給定類別,也爲所有子類。這適用於特殊的「自制」樹形圖,其中所有類別都根據層次顯示;當用戶點擊一個類別時,它會顯示屬於該類別的所有項目以及屬於該子類別的所有項目。希望你明白這個主意。

/****** Object: Table [dbo].[mz_category] Script Date: 04/26/2012 19:14:34 ******/ 
SET ARITHABORT ON 
GO 
SET CONCAT_NULL_YIELDS_NULL ON 
GO 
SET ANSI_NULLS ON 
GO 
SET ANSI_PADDING ON 
GO 
SET ANSI_WARNINGS ON 
GO 
SET NUMERIC_ROUNDABORT OFF 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
SET ANSI_PADDING ON 
GO 
SET ARITHABORT ON 
GO 
/****** Categories Table ******/ 
CREATE TABLE [dbo].[mz_category](
    [CatNode] [hierarchyid] NOT NULL, 
    [CatLevel] AS ([CatNode].[GetLevel]()), 
    [CatID] [int] NOT NULL, 
    [CatName] [varchar](80) NOT NULL, 
    [SectorId] [varchar](2) NULL, 
    [CatIcon] [varchar](255) NULL, 
    [oldCat] [varchar](8) NULL, 
PRIMARY KEY CLUSTERED 
(
    [CatNode] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY], 
UNIQUE NONCLUSTERED 
(
    [CatID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 
SET ANSI_PADDING OFF 
GO 
/****** Object: Table [dbo].[ic_item_cat] Script Date: 04/26/2012 19:14:34 ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
SET ANSI_PADDING ON 
GO 
/****** Items Table ******/ 
CREATE TABLE [dbo].[ic_item_cat](
    [item_code] [varchar](25) NOT NULL, 
    [item_description] [varchar](80) NULL, 
    [item_sector] [varchar](2) NULL, 
    [item_line] [varchar](2) NULL, 
    [item_reference] [varchar](50) NULL, 
    [item_upcean] [varchar](50) NULL, 
    [item_category] [int] NULL, 
    [item_brand] [varchar](8) NULL, 
    [item_cost] [decimal](12, 4) NULL, 
    [item_price1] [decimal](12, 4) NULL, 
    [item_price2] [decimal](12, 4) NULL, 
    [item_price3] [decimal](12, 4) NULL, 
    [item_webprice] [decimal](12, 4) NULL, 
    [item_dprice1] [decimal](12, 4) NULL, 
    [item_dprice2] [decimal](12, 4) NULL, 
    [item_dprice3] [decimal](12, 4) NULL, 
    [item_lastcost] [decimal](12, 4) NULL, 
    [item_lastcostdate] [datetime] NULL, 
    [item_lastqtyout] [decimal](12, 4) NULL, 
    [item_lastqtyoutdate] [datetime] NULL, 
    [item_lastqtyin] [decimal](12, 4) NULL, 
    [item_lastqtyindate] [datetime] NULL, 
    [item_additionaldesc] [varchar](max) NULL, 
    [item_weight] [decimal](12, 4) NULL, 
    [item_weight_measure] [varchar](2) NULL, 
    [item_width] [decimal](12, 4) NULL, 
    [item_width_measure] [varchar](2) NULL, 
    [item_length] [decimal](12, 4) NULL, 
    [item_length_measure] [varchar](2) NULL, 
    [item_height] [decimal](12, 4) NULL, 
    [item_height_measure] [varchar](2) NULL, 
    [item_whpackdesc] [varchar](80) NULL, 
    [item_salespackdesc] [varchar](80) NULL, 
    [item_purchpackdesc] [varchar](80) NULL, 
    [item_salespackconv] [decimal](12, 4) NULL, 
    [item_purchpackconv] [decimal](12, 4) NULL, 
    [item_warranty] [varchar](2) NULL, 
    [item_delivtime] [varchar](2) NULL, 
    [item_rating] [int] NULL, 
    [item_vat] [varchar](2) NULL, 
    [item_status] [int] NULL, 
    [item_avgleadtime] [int] NULL, 
    [web_flag] [bit] NULL, 
    [partner_id] [varchar](25) NULL, 
    [unique_id] [uniqueidentifier] NOT NULL 
) ON [PRIMARY] 
GO 
SET ANSI_PADDING OFF 
GO 
+0

您使用的是什麼RDBMS? – 2012-04-26 08:37:02

+0

我正在使用SQL Server 2008 R2 – Carlos 2012-04-26 08:41:48

回答

1

會有這樣的工作嗎?

DECLARE @CatNode hierarchyid; 
SET @CatNode = (
    SELECT CatNode from mz_category 
    WHERE CatID = @CatID 
); 
SELECT * FROM Items 
WHERE CatID IN (
    SELECT CatID 
    FROM mz_category 
    WHERE CatNode.IsDescendantOf(@CatNode) = 1 
); 
+0

不幸的是,這並不好。它顯示項目表中的所有行。雖然代碼必須改變,除非你有進一步的解釋。 @ mz_category沒有聲明,我認爲它是表名mz-category,所以我刪除了@。 – Carlos 2012-04-26 19:18:34

+0

糟糕。應該是IsDescendantOf(@CatNode)。編輯。 – 2012-04-26 21:38:07

+0

這工作完美!非常感謝,夥伴。現在是我繼續學習和獨奏的時候了。 – Carlos 2012-04-27 07:24:18

1

您可以使用CTE

  • 選擇起始記錄(S)
  • 獲取這些起始記錄(S)的孩子在遞歸部分

SQL語句

;WITH q AS (
    SELECT CatID, Parent, Name 
    FROM YourTable 
    WHERE CatID = 3 
    UNION ALL 
    SELECT t.CatID, t.Parent, t.Name 
    FROM q 
      INNER JOIN YourTable t ON t.Parent = q.CatID 
) 
SELECT * 
FROM q 
+0

感謝您的輸入。也許我在帖子中還不夠清楚。我試圖實現的是有一個查詢,ic_item表(項目)列出屬於一個類別的所有項目和該類別的所有孩子。我知道如何使用IsDescendantOf構建查詢,以便從節點獲取所有子節點,但我不知道如何將它加入到項目表中。 – Carlos 2012-04-26 11:29:38

+0

對不起,我不知道你需要什麼。在我們參與20問題遊戲之前,您應該至少發佈模式。理想的做法是包括一些測試數據和預期輸出。 – 2012-04-26 13:12:32

+0

發佈我想要實現的模式和簡要說明 – Carlos 2012-04-26 17:34:58

0
DECLARE @CatID hierarchyid = '/6/'; 

WITH RootCategory AS (
    SELECT CatID, 
      Parent, 
      Name 
    FROM Category 
    WHERE CatID = @CatID 

    UNION ALL 

    SELECT  C.CatID, 
       C.Parent, 
       C.Name 
    FROM  Category C 
    INNER JOIN RootCategory R ON C.Parent = R.CatID 
) 
SELECT * 
FROM RootCategory 
+0

感謝您的意見。也許我在帖子中還不夠清楚。我試圖實現的是有一個查詢,ic_item表(項目)列出屬於一個類別的所有項目和該類別的所有孩子。我知道如何使用IsDescendantOf構建查詢,以便從節點獲取所有子節點,但我不知道如何將它加入到項目表中。 – Carlos 2012-04-26 11:29:30

+1

您可以發佈您的物品表架構嗎?沒有這些信息,我無法編寫該查詢。 – weenoid 2012-04-26 12:05:25

+0

發佈了我試圖實現的模式和簡要說明 – Carlos 2012-04-26 17:34:48