SQL Server:从嵌套类别层次结构中获取产品的查询

ros*_*sko 1 sql sql-server common-table-expression

我的 SQL 查询有问题。我这里有两个 SQL Server 表。

第一个:

CREATE TABLE [category].[Categories](
    [Id] [bigint] IDENTITY(1,1) NOT NULL, -- PRIMARY KEY
    [Name] [nvarchar](200) NOT NULL,
    [ParentId] [bigint] NULL -- CONSTRAINT [FK_Categories_Categories] FOREIGN KEY([ParentId])
);
Run Code Online (Sandbox Code Playgroud)

第二个是:

CREATE TABLE [product].[Products](
    [Id] [bigint] IDENTITY(1,1) NOT NULL, -- PRIMARY KEY
    [Name] [nvarchar](250) NOT NULL,
    [CategoryId] [bigint] NOT NULL, -- CONSTRAINT [FK_Products_Categories] FOREIGN KEY([CategoryId])
    [Description] [nvarchar](500) NULL,
    [ManufacturerUrl] [nvarchar](1000) NULL,
    [ImageUrl] [nvarchar](1000) NULL,
    [Price] [money] NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

假设有一个类别层次结构:

  • 电子产品(id = 1,parentId = null)
    • 相机(id = 3,parentId = 1)
    • 计算机(id = 4,parentId = 1)
    • 手机(id = 5,parentId = 1)
      • 手机和智能手机(id = 8,parentId = 5)
      • 手机配件(id = 9,parentId = 5)
  • 电机(id = 2,parentId = null)
    • 等(id = 6,parentId = 2)
    • 等(id = 7,parentId = 2)

我想要的是能够通过仅指定类别 id 来选择产品。

例如:假设我们想要获取 id = 1 类别下的所有产品
结果:我们从以下类别中获取所有产品:相机、计算机、手机(手机和智能手机 + 手机配件)

例如2:假设我们想要获取 id = 5 类别下的所有产品
结果:我们从以下位置获取所有产品:手机和智能手机 + 手机配件)

目前我只有这个查询:

With Categories_CTE As
(
    Select Id, Name, ParentId
    From category.Categories
    Where Id = **SOME CATEGORY ID**

    Union All
    Select t.Id, t.Name, t.ParentId
    From category.Categories t
    Inner Join Categories_CTE c On c.Id = t.ParentId
)

Select Id, Name, ParentId
From Categories_CTE;
Run Code Online (Sandbox Code Playgroud)

这让我得到了类别的层次结构,但这不是我真正想要的......

那么,有人可以帮助我吗?

先感谢您。

Mat*_*eld 5

只需加入您所在位置的产品即可...

With Categories_CTE As
(
    Select Id, Name, ParentId
    From category.Categories
    Where Id = **SOME CATEGORY ID**

    Union All
    Select t.Id, t.Name, t.ParentId
    From category.Categories t
    Inner Join Categories_CTE c On c.Id = t.ParentId
)

Select p.*
From Categories_CTE c INNER JOIN product.Products p on p.CategoryId = c.Id;
Run Code Online (Sandbox Code Playgroud)

注意:实际上不要在生产代码中使用 p.*,而是明确指定列。