当前位置: 代码迷 >> Sql Server >> 一个报表,但很难,根据数据之间的关系排序,求查询语句
  详细解决方案

一个报表,但很难,根据数据之间的关系排序,求查询语句

热度:57   发布时间:2016-04-24 10:49:19.0
一个表格,但很难,根据数据之间的关系排序,求查询语句。
比如,有一个队列:
马雷(第1个),郑平(第2个),胡涛(第3个),刘三(第4个),陈雨(第5个),.....数据库表(ShunxuTb)记录如下:
XuHao, ManName, ManPrior
1,马雷,null
2,刘三,胡涛
3,郑平,马雷
4,胡涛,郑平
5,陈雨,刘三
... ...

Xuhao字段没有实际意义,只是关键值;
ManName名字;
ManPrior表示前面的人。
马雷前面没有人,所以是第一个;
前面是马雷的是郑平,所以郑平是第二个;
前面是郑平的是胡涛,所以胡涛是第三个;
... ...
现在要寻找这样的查询语句,查询出来的结果是
ManName,
马雷,
郑平,
胡涛,
刘三,
陈雨,
... ...
这样的顺序。首先谢谢参与!
------解决方案--------------------
通过递归查询来实现:



;with t(XuHao, ManName, ManPrior)
as
(
select 1,'马雷',null
union all select 2,'刘三','胡涛'
union all select 3,'郑平','马雷'
union all select 4,'胡涛','郑平'
union all select 5,'陈雨','刘三'
),

tt
as
(
select manname,manprior,1 as level from t
where manprior is null

union all

select t.ManName,t.ManPrior,level + 1 
from tt
inner join t
        on tt.ManName = t.ManPrior
)

select manname
from tt
/*
manname
马雷
郑平
胡涛
刘三
陈雨
*/

------解决方案--------------------

if object_id('Tempdb..#t') is not null drop table #t
create table #t(
xuhao int identity(1,1) not null,
ManName nvarchar(10) null,
ManPrior nvarchar(10) null
)

Insert Into #t
select '马雷',null union all
select '刘三','胡涛' union all
select '郑平','马雷' union all
select '胡涛','郑平' union all
select '陈雨','刘三'

;with cte as(
select a.*,isnull(b.xuhao,0) as pid from #t a left join #t b on a.ManPrior=b.ManName
)
select xuhao,ManName,ManPrior from cte order by pid
--------------
xuhao       ManName    ManPrior
----------- ---------- ----------
1           马雷         NULL
3           郑平         马雷
5           陈雨         刘三
4           胡涛         郑平
2           刘三         胡涛

(5 行受影响)

------解决方案--------------------
引用:
感谢以上高手的回复,让我有幸学习了SQL2005及更新版的with语句的递归功能,遗憾的是我使用的SQL2000,恰好这个版本没有这个功能,能不能通过变通的方法实现这个功能呢?


用这个试试:


--drop table tb

create table tb(XuHao int, ManName nvarchar(20), ManPrior nvarchar(20))

insert into tb
select 1,'马雷',null
union all select 2,'刘三','胡涛'
union all select 3,'郑平','马雷'
union all select 4,'胡涛','郑平'
union all select 5,'陈雨','刘三'


select a.ManName
from tb a 
left join tb b 
       on a.ManPrior=b.ManName
order by isnull(b.xuhao,0)
/*
ManName
马雷
郑平
陈雨
胡涛
刘三
*/

------解决方案--------------------

--sql2000 版本
--创建测试数据
if object_id('tb') is not null drop table tb
go
create table tb(XuHao int, ManName nvarchar(20), ManPrior nvarchar(20))
 
insert into tb
select 1,'马雷',null
union all select 2,'刘三','胡涛'
union all select 3,'郑平','马雷'
union all select 4,'胡涛','郑平'
union all select 5,'陈雨','刘三'
go
--查询指定节点及其所有子节点的函数 
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[f_Cid]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[f_Cid]
go
CREATE FUNCTION f_Cid(@ManName varchar(20)) 
RETURNS @t_Level TABLE(ManName varchar(20),Level int) 
AS 
BEGIN 
DECLARE @Level int 
SET @Level=1 
INSERT @t_Level SELECT @ManName,@Level 
WHILE @@ROWCOUNT>0 
BEGIN 
SET @Level=@Level+1 
INSERT @t_Level SELECT a.ManName,@Level 
FROM tb a,@t_Level b 
WHERE a.ManPrior=b.ManName 
AND b.Level=@Level-1 
END 
RETURN 
END 
GO 

select * from f_Cid('马雷')

/*
manname   level
马雷      1
郑平      2
胡涛      3
  相关解决方案