求一个SQL排序,大家支持下

akuzou 2011-12-20 04:45:27
create table T(id varchar(50),tname varchar(50),tpath varchar(50),indextime datetime)

insert T

select '4b5d5056-58b7-4065-8ca9-21bd50c70c58','123456','087016','2011-12-16 09:48:01.810'
union all select '05527C13-3470-4CC0-AA75-A2512C407DC5','闪电买入价格以0.01微调','087016001','2011-12-19 09:06:08.855'
union all select '3BF1C178-627A-411C-B1B7-6E0D139868EC','鼠标悬停盘口价格以外的区域','087016002','2011-12-19 09:06:10.543'
union all select 'C77BB005-3E39-433D-B1D7-1D26E8C85186','锁定交易终端时,单击盘口弹出解锁窗体','087004','2011-12-16 09:47:56.309'
union all select 'D5CEAE3E-D0C1-4D9D-B55D-30482C0997D5','闪电交易窗体顶部Tab正确','087006','2011-12-16 09:47:57.809'
union all select 'B6357CF1-93E4-4053-AFBA-FEABF3FBF0F2','不登录交易终端单击盘口','087008','2011-12-16 09:48:33.466'
union all select '72809f19-72e0-4f0a-b562-c885199efbb2','8484','087009','2011-12-16 09:48:53.900'
union all select 'E0D1D497-A29E-4BE3-83FC-CA2D722D1195','闪电买入上市首日新股价格无限制','087011','2011-12-16 09:49:13.513'

select * from T

drop table T


排序要求为:树节点同一平级按indextime升序排,但先要排完某节点下面的所有子节点,再排下一个节点,上面测试数据的排序要求结果为:
id tname tpath indextime
------------------ -------------------------------------------------- -----------------------
C77BB005-3E39-433D-B1D7-1D26E8C85186 锁定交易终端时,单击盘口弹出解锁窗体 087004 2011-12-16 09:47:56.310
D5CEAE3E-D0C1-4D9D-B55D-30482C0997D5 闪电交易窗体顶部Tab正确 087006 2011-12-16 09:47:57.810
4b5d5056-58b7-4065-8ca9-21bd50c70c58 123456 087016 2011-12-19 09:06:08.855
05527C13-3470-4CC0-AA75-A2512C407DC5 闪电买入价格以0.01微调 087016001 2011-12-19 09:06:08.857
3BF1C178-627A-411C-B1B7-6E0D139868EC 鼠标悬停盘口价格以外的区域 087016002 2011-12-19 09:06:10.543
B6357CF1-93E4-4053-AFBA-FEABF3FBF0F2 不登录交易终端单击盘口 087008 2011-12-16 09:48:33.467
72809f19-72e0-4f0a-b562-c885199efbb2 8484 087009 2011-12-16 09:48:53.900
E0D1D497-A29E-4BE3-83FC-CA2D722D1195 闪电买入上市首日新股价格无限制 087011 2011-12-16 09:49:13.513
...全文
126 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
akuzou 2011-12-20
  • 打赏
  • 举报
回复
谢谢大家了,还是选择使用了小F的with递归方法
-晴天 2011-12-20
  • 打赏
  • 举报
回复
不过,楼主这样的处理非常不好,一是排序不方便,二是,由于每节只是一个字符包含数量不多(如果加上26个英文字母可有36个,但生成时麻烦一些),三是不够直观.
不清楚为什么楼主不直接从第四位开始向下处理,而是从第六位开始向上处理.
-晴天 2011-12-20
  • 打赏
  • 举报
回复
如果楼主的上下级关系仅仅为:第6位是根,其子及孙分别为第5位和第4位,再下去看第7位及以下的从左向右的顺序,那可以这样:
create table T(id varchar(50),tname varchar(50),tpath varchar(50),indextime datetime)

insert T

select '4b5d5056-58b7-4065-8ca9-21bd50c70c58','123456','087016','2011-12-16 09:48:01.810'
union all select '05527C13-3470-4CC0-AA75-A2512C407DC5','闪电买入价格以0.01微调','087016001','2011-12-19 09:06:08.855'
union all select '3BF1C178-627A-411C-B1B7-6E0D139868EC','鼠标悬停盘口价格以外的区域','087016002','2011-12-19 09:06:10.543'
union all select 'C77BB005-3E39-433D-B1D7-1D26E8C85186','锁定交易终端时,单击盘口弹出解锁窗体','087004','2011-12-16 09:47:56.309'
union all select 'D5CEAE3E-D0C1-4D9D-B55D-30482C0997D5','闪电交易窗体顶部Tab正确','087006','2011-12-16 09:47:57.809'
union all select 'B6357CF1-93E4-4053-AFBA-FEABF3FBF0F2','不登录交易终端单击盘口','087008','2011-12-16 09:48:33.466'
union all select '72809f19-72e0-4f0a-b562-c885199efbb2','8484','087009','2011-12-16 09:48:53.900'
union all select 'E0D1D497-A29E-4BE3-83FC-CA2D722D1195','闪电买入上市首日新股价格无限制','087011','2011-12-16 09:49:13.513'
go
select * from T order by STUFF(tpath,4,3,reverse(substring(tpath,4,3))),indextime
/*
id tname tpath indextime
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -----------------------
E0D1D497-A29E-4BE3-83FC-CA2D722D1195 闪电买入上市首日新股价格无限制 087011 2011-12-16 09:49:13.513
C77BB005-3E39-433D-B1D7-1D26E8C85186 锁定交易终端时,单击盘口弹出解锁窗体 087004 2011-12-16 09:47:56.310
D5CEAE3E-D0C1-4D9D-B55D-30482C0997D5 闪电交易窗体顶部Tab正确 087006 2011-12-16 09:47:57.810
4b5d5056-58b7-4065-8ca9-21bd50c70c58 123456 087016 2011-12-16 09:48:01.810
05527C13-3470-4CC0-AA75-A2512C407DC5 闪电买入价格以0.01微调 087016001 2011-12-19 09:06:08.857
3BF1C178-627A-411C-B1B7-6E0D139868EC 鼠标悬停盘口价格以外的区域 087016002 2011-12-19 09:06:10.543
B6357CF1-93E4-4053-AFBA-FEABF3FBF0F2 不登录交易终端单击盘口 087008 2011-12-16 09:48:33.467
72809f19-72e0-4f0a-b562-c885199efbb2 8484 087009 2011-12-16 09:48:53.900

(8 行受影响)

*/
go
drop table T

akuzou 2011-12-20
  • 打赏
  • 举报
回复
087016001是087016的子节点
-晴天 2011-12-20
  • 打赏
  • 举报
回复
楼主给出的结果有误:
087011 的上级 是 087001,因此它必须排到最前面才对,尽管在给出的数据中没有看到087001
-晴天 2011-12-20
  • 打赏
  • 举报
回复
楼主, 087016 是 087006 的子节点?
那如果有 087001,你这个排序该是怎么个排法?
还有,087506 的上级节点是什么?
akuzou 2011-12-20
  • 打赏
  • 举报
回复
还应该是不行的,这样的话087016
087016001
087016002
这三条数据就放在一组排序了.

在发贴之前我写个算法:每个节点都是根据他的父节点indextime先排序,然后再本级节点排. 但是是有BUG的;因为树节点深度不一样,所以以有可能排序父节点其实并不是平级的
快溜 2011-12-20
  • 打赏
  • 举报
回复
order by (select min(indextime) from t where LEFT(tpath,6)=LEFT(a.tpath,6)),indextime
akuzou 2011-12-20
  • 打赏
  • 举报
回复
to 今生为你还:
算法是有问题的,演变了下,会发现前6位一样的情况下排序值是一样的,为什么会出现排序效果,是因为插进去的数据是有排序效果的.
select *,(select min(indextime) from t where LEFT(tpath,6)=LEFT(a.tpath,6)) from t a
-晴天 2011-12-20
  • 打赏
  • 举报
回复
好像还是用递归来做比较灵活点,用递归根据树的分支产生一个序列,然后直接用这个序列排序就行了.
快溜 2011-12-20
  • 打赏
  • 举报
回复
6必须取查询数据的根节点字段长度,具体不知道你数据怎么分布
akuzou 2011-12-20
  • 打赏
  • 举报
回复
to : ssp2009
看是看懂了,但没想到如何变通.
意思是树深度不固定时,LEFT(tpath,6) 这个里面的6如何参数掉
昵称被占用了 2011-12-20
  • 打赏
  • 举报
回复
DECLARE @T table (id varchar(50),tname varchar(50),tpath varchar(50),indextime datetime)

insert @T

select '4b5d5056-58b7-4065-8ca9-21bd50c70c58','123456','087016','2011-12-16 09:48:01.810'
union all select '05527C13-3470-4CC0-AA75-A2512C407DC5','闪电买入价格以0.01微调','087016001','2011-12-19 09:06:08.855'
union all select '3BF1C178-627A-411C-B1B7-6E0D139868EC','鼠标悬停盘口价格以外的区域','087016002','2011-12-19 09:06:10.543'
union all select 'C77BB005-3E39-433D-B1D7-1D26E8C85186','锁定交易终端时,单击盘口弹出解锁窗体','087004','2011-12-16 09:47:56.309'
union all select 'D5CEAE3E-D0C1-4D9D-B55D-30482C0997D5','闪电交易窗体顶部Tab正确','087006','2011-12-16 09:47:57.809'
union all select 'B6357CF1-93E4-4053-AFBA-FEABF3FBF0F2','不登录交易终端单击盘口','087008','2011-12-16 09:48:33.466'
union all select '72809f19-72e0-4f0a-b562-c885199efbb2','8484','087009','2011-12-16 09:48:53.900'
union all select 'E0D1D497-A29E-4BE3-83FC-CA2D722D1195','闪电买入上市首日新股价格无限制','087011','2011-12-16 09:49:13.513'


SELECT * FROM @T A
ORDER BY (SELECT TOP 1 indextime FROM @T WHERE tpath = LEFT(A.tpath,3))
,(SELECT TOP 1 indextime FROM @T WHERE tpath = LEFT(A.tpath,6))
,indextime

-- 结果
id tname tpath indextime
C77BB005-3E39-433D-B1D7-1D26E8C85186 锁定交易终端时,单击盘口弹出解锁窗体 087004 2011-12-16 09:47:56.310
D5CEAE3E-D0C1-4D9D-B55D-30482C0997D5 闪电交易窗体顶部Tab正确 087006 2011-12-16 09:47:57.810
4b5d5056-58b7-4065-8ca9-21bd50c70c58 123456 087016 2011-12-16 09:48:01.810
05527C13-3470-4CC0-AA75-A2512C407DC5 闪电买入价格以0.01微调 087016001 2011-12-19 09:06:08.857
3BF1C178-627A-411C-B1B7-6E0D139868EC 鼠标悬停盘口价格以外的区域 087016002 2011-12-19 09:06:10.543
B6357CF1-93E4-4053-AFBA-FEABF3FBF0F2 不登录交易终端单击盘口 087008 2011-12-16 09:48:33.467
72809f19-72e0-4f0a-b562-c885199efbb2 8484 087009 2011-12-16 09:48:53.900
E0D1D497-A29E-4BE3-83FC-CA2D722D1195 闪电买入上市首日新股价格无限制 087011 2011-12-16 09:49:13.513
昵称被占用了 2011-12-20
  • 打赏
  • 举报
回复
SEELCT * FROM T A
ORDER BY (SELECT TOP 1 indextime FROM T WHERE tpath = LEFT(A.tpath,3))
,(SELECT TOP 1 indextime FROM T WHERE tpath = LEFT(A.tpath,6))
,indextime
q465897859 2011-12-20
  • 打赏
  • 举报
回复
都没有父节点 就那些数据直接排序 如果有父节点 可以用递归 参考小F
昵称被占用了 2011-12-20
  • 打赏
  • 举报
回复
ORDER BY tpath
不行吗
快溜 2011-12-20
  • 打赏
  • 举报
回复
create table T(id varchar(50),tname varchar(50),tpath varchar(50),indextime datetime)

insert T

select '4b5d5056-58b7-4065-8ca9-21bd50c70c58','123456','087016','2011-12-16 09:48:01.810'
union all select '05527C13-3470-4CC0-AA75-A2512C407DC5','闪电买入价格以0.01微调','087016001','2011-12-19 09:06:08.855'
union all select '3BF1C178-627A-411C-B1B7-6E0D139868EC','鼠标悬停盘口价格以外的区域','087016002','2011-12-19 09:06:10.543'
union all select 'C77BB005-3E39-433D-B1D7-1D26E8C85186','锁定交易终端时,单击盘口弹出解锁窗体','087004','2011-12-16 09:47:56.309'
union all select 'D5CEAE3E-D0C1-4D9D-B55D-30482C0997D5','闪电交易窗体顶部Tab正确','087006','2011-12-16 09:47:57.809'
union all select 'B6357CF1-93E4-4053-AFBA-FEABF3FBF0F2','不登录交易终端单击盘口','087008','2011-12-16 09:48:33.466'
union all select '72809f19-72e0-4f0a-b562-c885199efbb2','8484','087009','2011-12-16 09:48:53.900'
union all select 'E0D1D497-A29E-4BE3-83FC-CA2D722D1195','闪电买入上市首日新股价格无限制','087011','2011-12-16 09:49:13.513'

select * from t a
order by (select min(indextime) from t where LEFT(tpath,6)=LEFT(a.tpath,6))

/*
id tname tpath indextime
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -----------------------
C77BB005-3E39-433D-B1D7-1D26E8C85186 锁定交易终端时,单击盘口弹出解锁窗体 087004 2011-12-16 09:47:56.310
D5CEAE3E-D0C1-4D9D-B55D-30482C0997D5 闪电交易窗体顶部Tab正确 087006 2011-12-16 09:47:57.810
4b5d5056-58b7-4065-8ca9-21bd50c70c58 123456 087016 2011-12-16 09:48:01.810
05527C13-3470-4CC0-AA75-A2512C407DC5 闪电买入价格以0.01微调 087016001 2011-12-19 09:06:08.857
3BF1C178-627A-411C-B1B7-6E0D139868EC 鼠标悬停盘口价格以外的区域 087016002 2011-12-19 09:06:10.543
B6357CF1-93E4-4053-AFBA-FEABF3FBF0F2 不登录交易终端单击盘口 087008 2011-12-16 09:48:33.467
72809f19-72e0-4f0a-b562-c885199efbb2 8484 087009 2011-12-16 09:48:53.900
E0D1D497-A29E-4BE3-83FC-CA2D722D1195 闪电买入上市首日新股价格无限制 087011 2011-12-16 09:49:13.513

(8 行受影响)
--小F-- 2011-12-20
  • 打赏
  • 举报
回复
就是BOM 按节点排序。
--小F-- 2011-12-20
  • 打赏
  • 举报
回复
BOM按节点排序应用实例 
--------------------------------------------------------------------------

-- Author : htl258(Tony)

-- Date : 2010-04-23 02:37:28

-- Version:Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86)

-- Jul 9 2008 14:43:34

-- Copyright (c) 1988-2008 Microsoft Corporation

-- Developer Edition on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)

-- Subject: BOM按节点排序应用实例

--------------------------------------------------------------------------



--实例1:

--> 生成测试数据表:tb



IF NOT OBJECT_ID('[tb]') IS NULL

DROP TABLE [tb]

GO

CREATE TABLE [tb]([id] INT,[code] NVARCHAR(10),[pid] INT,[name] NVARCHAR(10))

INSERT [tb]

SELECT 1,'01',0,N'服装' UNION ALL

SELECT 2,'01',1,N'男装' UNION ALL

SELECT 3,'01',2,N'西装' UNION ALL

SELECT 4,'01',3,N'全毛' UNION ALL

SELECT 5,'02',3,N'化纤' UNION ALL

SELECT 6,'02',2,N'休闲装' UNION ALL

SELECT 7,'02',1,N'女装' UNION ALL

SELECT 8,'01',7,N'套装' UNION ALL

SELECT 9,'02',7,N'职业装' UNION ALL

SELECT 10,'03',7,N'休闲装' UNION ALL

SELECT 11,'04',7,N'西装' UNION ALL

SELECT 12,'01',11,N'全毛' UNION ALL

SELECT 13,'02',11,N'化纤' UNION ALL

SELECT 14,'05',7,N'休闲装'

GO

--SELECT * FROM [tb]



-->SQL查询如下:



;WITH T AS

(

SELECT CAST(CODE AS VARCHAR(20)) AS CODE,*,

CAST(ID AS VARBINARY(MAX)) AS px

FROM tb AS A

WHERE NOT EXISTS(SELECT * FROM tb WHERE id=A.pid)

UNION ALL

SELECT CAST(B.CODE+A.CODE AS VARCHAR(20)),A.*,

CAST(B.px+CAST(A.ID AS VARBINARY) AS VARBINARY(MAX))

FROM tb AS A

JOIN T AS B

ON A.pid=B.id

)

SELECT Code,Name FROM T

ORDER BY px

/*

Code Name

-------------------- ----------

01 服装

0101 男装

010101 西装

01010101 全毛

01010102 化纤

010102 休闲装

0102 女装

010201 套装

010202 职业装

010203 休闲装

010204 西装

01020401 全毛

01020402 化纤

010205 休闲装



(14 行受影响)

*/



--实例2:

--> 生成测试数据表:tb

IF NOT OBJECT_ID('[tb]') IS NULL
DROP TABLE [tb]
GO
CREATE TABLE [tb]([id] INT,[parentid] INT,[categoryname] NVARCHAR(10))
INSERT [tb]
SELECT 1,0,'test1' UNION ALL
SELECT 2,0,'test2' UNION ALL
SELECT 3,1,'test1.1' UNION ALL
SELECT 4,2,'test2.1' UNION ALL
SELECT 5,3,'test1.1.1' UNION ALL
SELECT 6,1,'test1.2'
GO
--SELECT * FROM [tb]

-->SQL查询如下:
;WITH T AS
(
SELECT *,CAST(ID AS VARBINARY(MAX)) AS px
FROM tb AS A
WHERE NOT EXISTS(SELECT * FROM tb WHERE id=A.[parentid])
UNION ALL
SELECT A.*,CAST(B.px+CAST(A.ID AS VARBINARY) AS VARBINARY(MAX))
FROM tb AS A
JOIN T AS B
ON A.[parentid]=B.id
)
SELECT [id],[parentid],[categoryname] FROM T
ORDER BY px
/*
id parentid categoryname
----------- ----------- ------------
1 0 test1
3 1 test1.1
5 3 test1.1.1
6 1 test1.2
2 0 test2
4 2 test2.1

(6 行受影响)
*/



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/htl258/archive/2010/04/23/5518166.aspx
tianshibuhuifei 2011-12-20
  • 打赏
  • 举报
回复
你这个子节点是什么概念

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧