我有两个表,一个是商品表。一个是类别表。
商品表里有商品编号、商品名称、类别编号。
类别表里有类别编号、类别名称和父类别编号。类别表是一个自连接的表。其中父类编号就是类别表的外键。例如存放数据为:
类别编号 类别名称 父类编号
1 食品 NULL
2 副食品 1
3 糖 2
4 白糖 3
5 红糖 3
6 绵白糖 4
7 梅花牌绵白糖 6
8 饮料 2
9 碳酸饮料 8
10 维生素饮料 8
11 雪碧 9
12 可乐 9
13 粒粒橙 10
14 主食品 1
15 肉类 14
16 蔬菜 14
商品表的类别编号是类别表的类别编号的外键,现在我需要根据一个类别编号的到这个类别的所有的子类的商品信息。例如我得到了副食品的类别编号为2,那么就要把关于副食品以及副食品的所有子类的商品信息全部查询出来,这里便当然就不应该包括主食品、肉类和蔬菜的商品信息。现在的一个关键问题是我不知道一个类别下面到底有多少字类别。
怎么写出SQL语句以满足这样的查询呢?先谢谢大虾了,我想了一个晚上了都没有想出来该怎么写 ,帮帮忙吧。
----创建测试数据
if object_id('tbType') is not null
drop table tbType
if object_id('tbTestProduct') is not null
drop table tbTestProduct
if object_id('fnGetChildren') is not null
drop function fnGetChildren
GO
create table tbType(类别编号 int,类别名称 varchar(20),父类编号 int)
insert tbType
select 1, '食品', NULL union all
select 2, '副食品', 1 union all
select 3, '糖', 2 union all
select 4, '白糖', 3 union all
select 5, '红糖', 3 union all
select 6, '绵白糖', 4 union all
select 7, '梅花牌绵白糖', 6 union all
select 8, '饮料', 2 union all
select 9, '碳酸饮料', 8 union all
select 10, '维生素饮料', 8 union all
select 11, '雪碧', 9 union all
select 12, '可乐', 9 union all
select 13, '粒粒橙', 10 union all
select 14, '主食品', 1 union all
select 15, '肉类', 14 union all
select 16, '蔬菜', 14
create table tbTestProduct(商品编号 int,商品名称 varchar(20),类别编号 int)
GO
----创建子结点查找函数
create function fnGetChildren(@id int)
returns @tmp table(类别编号 int,类别名称 varchar(20))
as
begin
insert @tmp select 类别编号,类别名称 from tbType where 类别编号 = @id
while @@rowcount > 0
insert @tmp select a.类别编号,a.类别名称 from tbType as a INNER JOIN @tmp as b
on a.父类编号 = b.类别编号 where a.类别编号 not in(select 类别编号 from @tmp)
return
end
GO
----查询所有子类
declare @id int
set @id = 2
select * from dbo.fnGetChildren(@id)
----查询子类的所有商品
select * from dbo.fnGetChildren(@id) as a
left join tbTestProduct as b on a.类别编号 = b.类别编号
----清除测试环境
drop table tbType,tbTestProduct
drop function fnGetChildren
/*结果
类别编号 类别名称
----------- --------------------
2 副食品
3 糖
8 饮料
4 白糖
5 红糖
9 碳酸饮料
10 维生素饮料
6 绵白糖
11 雪碧
12 可乐
13 粒粒橙
7 梅花牌绵白糖
(所影响的行数为 12 行)
*/