当前位置: 首页 > 知识库问答 >
问题:

任何类别或子类别中的顶级品牌列表

袁高明
2023-03-14

我正在使用SQLServer 2008,我迫切需要sql查询或存储过程来显示任何类别或子类别中的顶级品牌。例如,如果我通过Id分类=2,结果集应该通过执行id分类=2及其子类别和子类别的产品计数来显示电子产品中的顶级品牌。如果我通过Id分类=38,结果应该显示手机中的顶级品牌

以下是我数据库中的表格。

类别

IdCategory    CategoryName              ParentCategoryId
---------------------------------------------------------
1             Appliances                Null
2             Electronics               Null
38            Phones & Mobile Devices   2
39            Cameras & Photography     2
115           Mobile Phones             38
121           Digital Cameras           39

品牌

IdBrand       BrandName 
------------------------
1             Nokia
2             Samsung
3             Canon

下表打破了类别和品牌表之间的多对多关系

分类目录品牌

IdCategoriesBrand    IdCategory   IdBrand
-----------------------------------------
1                    2            1
2                    38           1
3                    115          1
4                    2            2
5                    38           2
6                    115          2

产品

IdProduct     Product Name       IdCategory    IdBrand
---------------------------------------------------------
1             AAAA               115           1
2             BBBB               115           2
3             CCCC               121           3
4             DDDD               115           1
5             EEEE               121           3

关于乘积表的假设

  • 产品只能添加到第三级子类别(例如手机,数码相机)

下面是创建表的脚本

CREATE TABLE [dbo].[Categories](
    [IdCategory] [bigint]  NOT NULL,
    [CategoryName] [nvarchar](50) NULL,  
    [ParentCategoryId] [bigint] NULL
    CONSTRAINT [PK_Categories_IdCategory] PRIMARY KEY CLUSTERED (   [IdCategory] ASC )
) ON [PRIMARY]

GO


CREATE TABLE [dbo].[Brands](
    [IdBrand] [bigint]  NOT NULL,
    [BrandName] [nvarchar](50) NULL
    CONSTRAINT [PK_Brands_IdBrand] PRIMARY KEY CLUSTERED (  [IdBrand] ASC )
) ON [PRIMARY]

GO

CREATE TABLE [dbo].[CategoriesBrands](
    [IdCategoriesBrand] [bigint]  NOT NULL,
    [IdCategory] [bigint] NULL,
    [IdBrand] [bigint] NULL,
    CONSTRAINT [PK_CategoriesBrands] PRIMARY KEY CLUSTERED (    [IdCategoriesBrand] ASC )
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[CategoriesBrands]  WITH CHECK ADD  CONSTRAINT [FK_CategoriesBrands_Brands] FOREIGN KEY([IdBrand])
REFERENCES [dbo].[Brands] ([IdBrand])
GO

ALTER TABLE [dbo].[CategoriesBrands] CHECK CONSTRAINT [FK_CategoriesBrands_Brands]
GO

ALTER TABLE [dbo].[CategoriesBrands]  WITH CHECK ADD  CONSTRAINT [FK_CategoriesBrands_Categories] FOREIGN KEY([IdCategory])
REFERENCES [dbo].[Categories] ([IdCategory])
GO

ALTER TABLE [dbo].[CategoriesBrands] CHECK CONSTRAINT [FK_CategoriesBrands_Categories]
GO

CREATE TABLE [dbo].[Products](
    [IdProduct] [bigint]  NOT NULL,
    [ProductName] [nvarchar](200) NULL,
    [IdCategory] [bigint] NULL,
    [IdBrand] [bigint] NULL 
    CONSTRAINT [PK_Products_IdProduct] PRIMARY KEY CLUSTERED (  [IdProduct] ASC )
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Products]  WITH CHECK ADD  CONSTRAINT [FK_Products_Brands] FOREIGN KEY([IdBrand])
REFERENCES [dbo].[Brands] ([IdBrand])
GO

ALTER TABLE [dbo].[Products] CHECK CONSTRAINT [FK_Products_Brands]
GO

ALTER TABLE [dbo].[Products]  WITH CHECK ADD  CONSTRAINT [FK_Products_Categories] FOREIGN KEY([IdCategory])
REFERENCES [dbo].[Categories] ([IdCategory])
GO

ALTER TABLE [dbo].[Products] CHECK CONSTRAINT [FK_Products_Categories]
GO

下面是在表中插入一些示例数据的脚本

INSERT INTO Categories (IdCategory, CategoryName, ParentCategoryId) VALUES(1, 'Appliances', NULL)
INSERT INTO Categories (IdCategory, CategoryName, ParentCategoryId) VALUES(2, 'Electronics', NULL)
INSERT INTO Categories (IdCategory, CategoryName, ParentCategoryId) VALUES(38, 'Phones & Mobile Devices', 2)
INSERT INTO Categories (IdCategory, CategoryName, ParentCategoryId) VALUES(39, 'Cameras & Photography', 2)
INSERT INTO Categories (IdCategory, CategoryName, ParentCategoryId) VALUES(115, 'Mobile Phones', 38)
INSERT INTO Categories (IdCategory, CategoryName, ParentCategoryId) VALUES(121, 'Digital Cameras', 39)


INSERT INTO Brands (IdBrand, BrandName) VALUES(1, 'Nokia')
INSERT INTO Brands (IdBrand, BrandName) VALUES(2, 'Samsung')
INSERT INTO Brands (IdBrand, BrandName) VALUES(3, 'Canon')


INSERT INTO CategoriesBrands (IdCategoriesBrand, IdCategory, IdBrand) VALUES(1, 2, 1)
INSERT INTO CategoriesBrands (IdCategoriesBrand, IdCategory, IdBrand) VALUES(2, 38, 1)
INSERT INTO CategoriesBrands (IdCategoriesBrand, IdCategory, IdBrand) VALUES(3, 115, 1)
INSERT INTO CategoriesBrands (IdCategoriesBrand, IdCategory, IdBrand) VALUES(4, 2, 2)
INSERT INTO CategoriesBrands (IdCategoriesBrand, IdCategory, IdBrand) VALUES(5, 38, 2)
INSERT INTO CategoriesBrands (IdCategoriesBrand, IdCategory, IdBrand) VALUES(6, 115, 2)


INSERT INTO Products (IdProduct, ProductName, IdCategory, IdBrand) VALUES(1, 'AAAA', 115, 1)
INSERT INTO Products (IdProduct, ProductName, IdCategory, IdBrand) VALUES(2, 'BBBB', 115, 2)
INSERT INTO Products (IdProduct, ProductName, IdCategory, IdBrand) VALUES(3, 'CCCC', 121, 3)
INSERT INTO Products (IdProduct, ProductName, IdCategory, IdBrand) VALUES(4, 'DDDD', 115, 1)
INSERT INTO Products (IdProduct, ProductName, IdCategory, IdBrand) VALUES(5, 'EEEE', 121, 3)

到目前为止,我已经尝试过这个方法,它给了我没有分类的前5个品牌

SELECT TOP 5
    b1.IdBrand, 
    ISNULL(b1.BrandName, '') AS BrandName, 
    count(p.IdProduct) AS 'ProductsCount'
FROM Brands b1
LEFT OUTER JOIN Products p
ON b1.IdBrand = p.IdBrand 
GROUP BY b1.IdBrand, b1.BrandName 
ORDER BY ProductsCount DESC

共有1个答案

景育
2023-03-14

以下是我解决这个问题的尝试:

    < li >首先获取所有类别,从根类别开始(使用递归CTE) < li >按类别计算品牌排名 < li >对于每个类别,显示前5个品牌

我还制作了一个SQLFIDLE,您可以在其中处理查询:http://sqlfiddle.com/#!3/8593b/12

这是代码:

declare @IdCategory bigint

set @IdCategory = 2

declare @selectedCategories
  table (IdCategory bigint primary key)


-- Use a recursive CTE to determine all
-- Categories that derive from current
-- Category
;with SelectedCategories as (
  select @IdCategory as IdCategory
  union all
  select c.IdCategory 
    from Categories c
    join SelectedCategories sc
      on sc.IdCategory = c.ParentCategoryId
)
-- Save Selected Categories
-- in a memory table
insert @selectedCategories (IdCategory)
select IdCategory from SelectedCategories

-- use another CTE to select the 
-- Brands in the Selected Categories
-- and compute their Category rank
-- using the RANK()
;with BrandsPerCategory as (
  select 
    c.IdCategory,
    cc.CategoryName,
    b.BrandName,
    rank() over (
      partition by c.IdCategory
      order by count(p.IdProduct) desc
    ) as BrandRank
  from @selectedCategories c
  join Categories cc
    on c.IdCategory = cc.IdCategory
  join CategoriesBrands cb
    on cb.IdCategory = c.IdCategory
  join Brands b
    on cb.IdBrand = b.IdBrand
  join Products p
    on p.IdBrand = b.IdBrand
  group by 
    c.IdCategory,
    cc.CategoryName,
    b.BrandName
)
select * 
from BrandsPerCategory
where BrandRank < 5
order by IdCategory, BrandRank 

编辑:

如果需要所有选定类别(根子类别)的顶级品牌,而不是上述示例中的每个类别,则可以使用以下查询(以及此 SqlFiddle):

declare @IdCategory bigint

set @IdCategory = 2

-- Use a recursive CTE to determine all
-- Categories that derive from current
-- Category
;with SelectedCategories as (
  select @IdCategory as IdCategory
  union all
  select c.IdCategory 
    from Categories c
    join SelectedCategories sc
      on sc.IdCategory = c.ParentCategoryId
)
select top 5
  b.IdBrand, 
  b.BrandName,
  count(p.IdProduct) AS 'ProductsCount'
from SelectedCategories c
join Categories cc
  on c.IdCategory = cc.IdCategory
join CategoriesBrands cb
  on cb.IdCategory = c.IdCategory
join Brands b
  on cb.IdBrand = b.IdBrand
join Products p
  on p.IdBrand = b.IdBrand
GROUP BY b.IdBrand, b.BrandName 
ORDER BY ProductsCount DESC

编辑2:(不将产品数量乘以相应类别品牌记录数量的解决方案):

http://sqlfiddle.com/#!3/26d60/8

代码:

;with SelectedCategories as (
  select @IdCategory as IdCategory
  union all
  select c.IdCategory 
    from Categories c
    join SelectedCategories sc
      on sc.IdCategory = c.ParentCategoryId
)
select top 5
  b.IdBrand, 
  b.BrandName,
  count(p.IdProduct) AS 'ProductsCount'
from Brands b
join Products p
  on p.IdBrand = b.IdBrand
where b.IdBrand in (
  select cb.IdBrand
  from SelectedCategories c
  join CategoriesBrands cb
    on cb.IdCategory = c.IdCategory
 )
GROUP BY b.IdBrand, b.BrandName 
ORDER BY ProductsCount DESC
 类似资料:
  • 我想做的是在我的WooCommerce商店的侧边栏上显示一个菜单,上面有当前产品类别名称和当前类别的子项。如果产品类别没有子类,那么它应该显示父类别和父类别子类。 这是层次结构的样子:商店 当你在“准备好的食物”页面上时,你应该看到。 制备食品 苦味 Charcuterie 食品 当你在食品页面上时,你应该看到 制备食品 苦味 Charcuterie 食品 现在,我已经让它在您处于顶级类别时显示父

  • 我有一个名为“产品类型”的WooCommerce产品类别,我试图列出该类别下的所有类别,但不是这些类别的子类别。例如,我有: 产品类型 碳化物米尔斯 钓鱼工具 儿童类别 我希望它列出“电石磨坊”和“打捞工具”,但不是“儿童类别”。 这是我的代码: 但它仍然返回“儿童类别”。我不知道为什么将深度限制为“1”并将“include_children”设置为“false”不能解决这个问题。

  • 问题内容: 我想在选择 列表(下拉列表)中显示类别,子类别和子子类别,就像WordPress在其管理面板中显示的方式一样。 首先看一下我的数据库表(tb_categories)- 数据库表 我想要以下HTML格式的输出- 输出 两项“无”和“未分类”在代码中进行了硬编码。我 想知道如何 使用选择列表选项以层次结构顺序显示类别及其子类别。 我正在尝试使用自我连接的以下sql查询。这 是- And t

  • 我目前有一个代码片段,其中对于每个类别,它将找到子类别: 将递归获取一个类别的子级: 目前,使用,只检索子类别的子类别,因此如果每个子类别都有自己的子类别,则不会将其保存到子类别中。 我如何显示子子类别给我们的子类别? 我想用我的代码做的是获取一个父级,获取它的子级,然后将这些子级中的每一个视为父级,递归地获取它的子级,但是我的JSON输出并没有反映这一点。只有父对象有子对象-子对象没有子对象(尽

  • 希望你能帮我解决这个问题。我有一个问题,一些产品在子类别404'ing当去那里的产品页面。但奇怪的是,我在谷歌上找不到的只是他们中的一些人在做这件事。 实例 SKU:产品1--类别:类别1 SKU:产品2--类别:类别2,子类别1 SKU:Product3--类别:类别2,子类别1 SKU:Product4--类别:类别2,子类别1 将显示Product1、Product2、Product4。带有

  • 我正试图通过WoodPress主题中的一个函数从woocommerce获取产品类别,我已经做到了: 这将按层次列出所有顶级类别及其下的子类别,但我有子类别(子类别)的子类别,因此如何列出这些子类别。