2012-04-26 130 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