表1:
ID NAME
表2:
ID NAME PID表3:
ID NAME GroupID表3的GroupID分别对应表1的ID和表2的ID,表2是张内联表。PID对应本表中的ID,也对应表1中的ID要提取出的是:表1中的Name和表3中的所有信息。条件是:GroupID和表1的ID对应,
ID NAME
表2:
ID NAME PID表3:
ID NAME GroupID表3的GroupID分别对应表1的ID和表2的ID,表2是张内联表。PID对应本表中的ID,也对应表1中的ID要提取出的是:表1中的Name和表3中的所有信息。条件是:GroupID和表1的ID对应,
select A.NAME,表3.[ID],表3.NAME,表3.GroupID from (select [ID],NAME,'' as PID from 表1 union select [ID],NAME,PID from 表2) A,表3 where A.[ID]=表3.GroupID
表3里就是具体的记录。通过GroupID标示是那个节点下的。要根据GroupID获得对应表1中的Name和本表中的信息
表3的GroupID分别对应表1的ID和表2的ID,怎么区分是表1的ID还是表2的ID
PID对应本表中的ID,也对应表1中的ID,又怎么区分这么多id什么类型,怎么编码
declare @b table (id int, name varchar(2),pid int)
declare @c table (id int, name varchar(2),groupid varchar(50))
insert @a
select 1,'a' union all
select 2,'b'
insert @b
select 1,'aa',1 union all
select 2,'bb',1 union all
select 3,'cc',1 union all
select 4,'dd',2
insert @c
select 1,'aa','aaaa' union all
select 1,'bb','bbbb' union all
select 1,'cc','cccc' union all
select 1,'dd','eeee'
select a.name,c.groupid
from @a a , @b b, @c c
where a.id=b.pid and b.name=c.name(所影响的行数为 2 行)
(所影响的行数为 4 行)
(所影响的行数为 4 行)name groupid
---- --------------------------------------------------
a aaaa
a bbbb
a cccc
b eeee(所影响的行数为 4 行)
from @a a , @b b, @c c
where a.id=b.pid and b.name=c.name(所影响的行数为 2 行)
(所影响的行数为 4 行)
(所影响的行数为 4 行)name id name groupid
---- ----------- ---- --------------------------------------------------
a 1 aa aaaa
a 1 bb bbbb
a 1 cc cccc
b 1 dd eeee(所影响的行数为 4 行)
from @a a left join @b b on a.id=b.pid left join @c c on b.name=c.name
drop function fnFindRoot
GO
----创建查找层次的函数,参数为表3GroupID值,返回值为表3中当前行对应于表2中的根节点ID
create function fnFindRoot(@id int)
returns int
as
begin
declare @pid int
select @pid = PID from 表2 where id = @id
while @@rowcount > 0
begin
select @pid = PID from 表2 where id = @pid
end
select @pid = id from 表2 where PID = @pid /*获得根节点的ID*/
return @pid /*返回根节点的ID*/
end
GO----查询
SELECT 表1.name,表3.* FROM 表3 LEFT JOIN 表1 ON 表1.id = dbo.fnFindRoot(表3.GroupID)
表3里就是具体的记录。通过GroupID标示是那个节点下的。要根据GroupID获得对应表1中的Name和本表中的信息
表1:
ID Name
1 aaa
2 bbb
表2:
ID Name Pid
-1 ccc 1
-2 ddd 1
-3 eee 2
-4 fff -1
-5 ggg -1
表3:
ID Name GroupID
1 hhh 1
2 jjj 2
3 kkk -1
运行后提示:
服务器: 消息 208,级别 16,状态 1,过程 fnFindRoot,行 13
对象名 '表2' 无效。
ID Name
1 aaa
2 bbb
3 ccc
表2:
ID Name Pid
-1 ccc 3
-2 ddd 1
-3 eee 2
-4 fff -1
-5 ggg -1
表3:
ID Name GroupID
1 hhh 1
2 jjj 1
3 kkk -1
要的结果:
aaa 1 hhh 1
aaa 1 hhh 1
ccc 3 kkk -1
aaa 1 hhh 1
aaa 1 jjj 1
ccc 3 kkk -1
drop table 表1
if object_id('表2') is not null
drop table 表2
if object_id('表3') is not null
drop table 表3
GO
----创建测试数据
create table 表1(ID int,Name varchar(10))
create table 表2(ID int,Name varchar(10),Pid int)
create table 表3(ID int,Name varchar(10),GroupID int)
GOinsert 表1
select 1, 'aaa' union all
select 2, 'bbb' union all
select 3, 'ccc'
insert 表2
select -1, 'ccc', 3 union all
select -2, 'ddd', 1 union all
select -3, 'eee', 2 union all
select -4, 'fff', -1 union all
select -5, 'ggg', -1
insert 表3
select 1, 'hhh', 1 union all
select 2, 'jjj', 1 union all
select 3, 'kkk', -1if object_id('fnFindRoot') is not null
drop function fnFindRoot
GO
----创建查找层次的函数,参数为表3GroupID值,返回值为表3中当前行对应于表2中的根节点ID
create function fnFindRoot(@id int)
returns int
as
begin
declare @pid int
if @id > 0
set @pid = @id /*如果表3.GroupID>0,则等于表1ID*/
else /*如果表3.GroupID<0,则找出根节点的PID*/
begin
select @pid = PID from 表2 where id = @id
while @@rowcount > 0
select @pid = PID from 表2 where id = @pid
end
return @pid /*返回根节点的ID*/
end
GO----查询
SELECT 表1.name,表3.* FROM 表3 LEFT JOIN 表1 ON 表1.id = dbo.fnFindRoot(表3.GroupID)----清除测试环境
drop table 表1,表2,表3
drop function fnFindRoot/*结果
name ID Name GroupID
--------------------------------------------------------------
aaa 1 hhh 1
aaa 2 jjj 1
ccc 3 kkk -1
*/