求一个查询的SQL语句或者是存储过程
我有两个表,一个是商品表。一个是类别表。
商品表里有商品编号、商品名称、类别编号。
类别表里有类别编号、类别名称和父类别编号。类别表是一个自连接的表。其中父类编号就是类别表的外键。例如存放数据为:
类别编号 类别名称 父类编号
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语句以满足这样的查询呢?先谢谢大虾了,我想了一个晚上了都没有想出来该怎么写 ,帮帮忙吧。
[解决办法]
--建立函
Create Function F_GetChildren(@类别编号 Int)
Returns @类别表 Table (类别编号 Int, 类别名称 Nvarchar(20), 父类编号 Int)
As
Begin
Insert @类别表 Select * From 类别表 Where 类别编号 = @类别编号 Or 父类编号 = @类别编号
While @@Rowcount > 0
Insert @类别表 Select A.* From 类别表 A Inner Join @类别表 B On A.父类编号 = B.类别编号 And A.类别编号 Not In (Select 类别编号 From @类别表)
Return
End
GO
--
Select * From dbo.F_GetChildren(2)
Select * From dbo.F_GetChildren(14)
[解决办法]
--建立境
Create Table 类别表
(类别编号 Int,
类别名称 Nvarchar(20),
父类编号 Int)
Insert 类别表 Select 1, N '食品 ', Null
Union All Select 2, N '副食品 ', 1
Union All Select 3, N '糖 ', 2
Union All Select 4, N '白糖 ', 3
Union All Select 5, N '红糖 ', 3
Union All Select 6, N '绵白糖 ', 4
Union All Select 7, N '梅花牌绵白糖 ', 6
Union All Select 8, N '饮料 ', 2
Union All Select 9, N '碳酸饮料 ', 8
Union All Select 10, N '维生素饮料 ', 8
Union All Select 11, N '雪碧 ', 9
Union All Select 12, N '可乐 ', 9
Union All Select 13, N '粒粒橙 ', 10
Union All Select 14, N '主食品 ', 1
Union All Select 15, N '肉类 ', 14
Union All Select 16, N '蔬菜 ', 14
GO
--建立函
Create Function F_GetChildren(@类别编号 Int)
Returns @类别表 Table (类别编号 Int, 类别名称 Nvarchar(20), 父类编号 Int)
As
Begin
Insert @类别表 Select * From 类别表 Where 类别编号 = @类别编号 Or 父类编号 = @类别编号
While @@Rowcount > 0
Insert @类别表 Select A.* From 类别表 A Inner Join @类别表 B On A.父类编号 = B.类别编号 And A.类别编号 Not In (Select 类别编号 From @类别表)
Return
End
GO
--
Select * From dbo.F_GetChildren(2) Order By 类别编号
Select * From dbo.F_GetChildren(14) Order By 类别编号
GO
--除境
Drop Table 类别表
Drop Function F_GetChildren
--果
/*
类别编号类别名称父类编号
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
*/
[解决办法]
----创建测试数据
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 行)
*/
[解决办法]
--如果需要存程
--建立境
Create Table 类别表
(类别编号 Int,
类别名称 Nvarchar(20),
父类编号 Int)
Insert 类别表 Select 1, N '食品 ', Null
Union All Select 2, N '副食品 ', 1
Union All Select 3, N '糖 ', 2
Union All Select 4, N '白糖 ', 3
Union All Select 5, N '红糖 ', 3
Union All Select 6, N '绵白糖 ', 4
Union All Select 7, N '梅花牌绵白糖 ', 6
Union All Select 8, N '饮料 ', 2
Union All Select 9, N '碳酸饮料 ', 8
Union All Select 10, N '维生素饮料 ', 8
Union All Select 11, N '雪碧 ', 9
Union All Select 12, N '可乐 ', 9
Union All Select 13, N '粒粒橙 ', 10
Union All Select 14, N '主食品 ', 1
Union All Select 15, N '肉类 ', 14
Union All Select 16, N '蔬菜 ', 14
GO
--建存程
Create ProceDure SP_GetChildren(@类别编号 Int)
As
Begin
Create Table #Tree(类别编号 Int, 类别名称 Nvarchar(20), 父类编号 Int)
Insert Into #Tree Select * From 类别表 Where 类别编号 = @类别编号
While @@Rowcount > 0
Insert #Tree Select A.* From 类别表 A Inner Join #Tree B On A.父类编号 = B.类别编号 And A.类别编号 Not In (Select 类别编号 From #Tree)
Select * From #Tree Order By 类别编号
Drop Table #Tree
Return
End
GO
--
EXEC SP_GetChildren 2
EXEC SP_GetChildren 14
GO
--除境
Drop Table 类别表
Drop ProceDure SP_GetChildren
--果
/*
类别编号类别名称父类编号
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
*/