层级树排序展示奇怪问题

lg3605119 2010-05-04 11:31:41
先从简单的一个语句排序来引导,以下语句执行结果排序为啥有差异?


select * from
(
select '0-16' as a union select '0-1-6'
)T
order by a
/*
0-16
0-1-6
*/

select * from
(
select '0-16' as a union select '0-1-5'
)T
order by a
/*
0-1-5
0-16
*/



CREATE TABLE [Department1](
[ID] [bigint] NOT NULL,
[No] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[Name] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[ParentID] [bigint] NULL
)

insert into [Department1]
select 1, 'DNMC', '运营公司', 0 union all
select 7, 'OPS', '生产部', 1 union all
select 8, 'aaaa', 'aaaa', 1 union all
select 9, 'bbbb', 'bbbb', 8 union all
select 10, 'cccc', 'cccc', 8 union all
select 11, 'ddd', 'dddd', 8 union all
select 12, 'vvv', '维修部', 1 union all
select 13, '2233', '技术部', 1 union all
select 14, 'eeee', 'eeee', 7 union all
select 15, 'ffff', 'ffff', 7 union all
select 16, 'test', 'test', 0 union all
select 17, 'rrrrr', 'rrrr', 7 union all
select 18, 'iiii', 'iiii', 10 union all
select 28, '33', '经理室', 13 union all
select 29, 'test111', 'test222', 1

;with SubTab([Level],[PID],[ID],[No],[Name],[Path]) as
(
select 1,[ParentID],[ID],[No],[Name],cast(ltrim(ParentID)+'-'+ltrim(ID) as varchar(4000))
from dbo.Department1
where [ParentID]=0
union all
select b.[Level]+1,a.[ParentID],a.[ID],a.[No],a.[Name],cast((b.[Path]+'-'+ltrim(a.[ID])) as varchar(4000))
from dbo.Department1 a,SubTab b
where a.[ParentID]=b.[ID]
)
select * from SubTab order by [Path]

/*
1 0 1 DNMC 运营公司 0-1
2 1 12 vvv 维修部 0-1-12
2 1 13 2233 技术部 0-1-13
3 13 28 33 经理室 0-1-13-28
2 1 29 test111 test222 0-1-29
1 0 16 test test 0-16
2 1 7 OPS 生产部 0-1-7
3 7 14 eeee eeee 0-1-7-14
3 7 15 ffff ffff 0-1-7-15
3 7 17 rrrrr rrrr 0-1-7-17
2 1 8 aaaa aaaa 0-1-8
3 8 10 cccc cccc 0-1-8-10
4 10 18 iiii iiii 0-1-8-10-18
3 8 11 ddd dddd 0-1-8-11
3 8 9 bbbb bbbb 0-1-8-9
*/

;with SubTab([Level],[PID],[ID],[No],[Name],[Path]) as
(
select 1,[ParentID],[ID],[No],[Name],cast(ltrim(ParentID)+'->'+ltrim(ID) as varchar(4000))
from dbo.Department1
where [ParentID]=0
union all
select b.[Level]+1,a.[ParentID],a.[ID],a.[No],a.[Name],cast((b.[Path]+'->'+ltrim(a.[ID])) as varchar(4000))
from dbo.Department1 a,SubTab b
where a.[ParentID]=b.[ID]
)
select * from SubTab order by [Path]
/* 正确结果
1 0 1 DNMC 运营公司 0->1
2 1 12 vvv 维修部 0->1->12
2 1 13 2233 技术部 0->1->13
3 13 28 33 经理室 0->1->13->28
2 1 29 test111 test222 0->1->29
2 1 7 OPS 生产部 0->1->7
3 7 14 eeee eeee 0->1->7->14
3 7 15 ffff ffff 0->1->7->15
3 7 17 rrrrr rrrr 0->1->7->17
2 1 8 aaaa aaaa 0->1->8
3 8 10 cccc cccc 0->1->8->10
4 10 18 iiii iiii 0->1->8->10->18
3 8 11 ddd dddd 0->1->8->11
3 8 9 bbbb bbbb 0->1->8->9
1 0 16 test test 0->16
*/

请各位发表自己的意见,谢谢!
...全文
186 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
htl258_Tony 2010-05-11
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 ldslove 的回复:]
引用 31 楼 ldslove 的回复:
是不是兄弟之间要按ID顺序排列


SQL code
CREATE TABLE [Department1](
[ID] [bigint] NOT NULL,
[No] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[Name] [nvarchar](50) COLLATE Chinese_PR……
[/Quote]这个结果跟7、10楼的一样,应该是树排序正确的结果。
东那个升 2010-05-11
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 ldslove 的回复:]
是不是兄弟之间要按ID顺序排列


SQL code
CREATE TABLE [Department1](
[ID] [bigint] NOT NULL,
[No] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[Name] [nvarchar](50) COLLATE Chinese_PRC_CI_AS N……
[/Quote]

写错



with SubTab as
(
select 1 as [Level],[ParentID],[ID],[No],[Name]
,cast(ltrim(ParentID)+'-'+ltrim(ID) as varchar(max)) as path
,CAST(row_number() over(order by id) as varBINARY(max)) as path1
from dbo.Department1
where [ParentID]=0
union all
select b.[Level]+1,a.[ParentID],a.[ID],a.[No],a.[Name]
,b.[Path]+'-'+ltrim(a.[ID])
,path1+CAST(row_number() over(partition by a.[ParentID] order by a.id) as BINARY(4))
from dbo.Department1 a,SubTab b
where a.[ParentID]=b.[ID]
)
select * from SubTab order by [Path1]


Level ParentID ID No Name path path1
----------- -------------------- -------------------- -------------------------------------------------- -------------------------------------------------- ---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
1 0 1 DNMC 运营公司 0-1 0x0000000000000001
2 1 7 OPS 生产部 0-1-7 0x000000000000000100000001
3 7 14 eeee eeee 0-1-7-14 0x00000000000000010000000100000001
3 7 15 ffff ffff 0-1-7-15 0x00000000000000010000000100000002
3 7 17 rrrrr rrrr 0-1-7-17 0x00000000000000010000000100000003
2 1 8 aaaa aaaa 0-1-8 0x000000000000000100000002
3 8 9 bbbb bbbb 0-1-8-9 0x00000000000000010000000200000001
3 8 10 cccc cccc 0-1-8-10 0x00000000000000010000000200000002
4 10 18 iiii iiii 0-1-8-10-18 0x0000000000000001000000020000000200000001
3 8 11 ddd dddd 0-1-8-11 0x00000000000000010000000200000003
2 1 12 vvv 维修部 0-1-12 0x000000000000000100000003
2 1 13 2233 技术部 0-1-13 0x000000000000000100000004
3 13 28 33 经理室 0-1-13-28 0x00000000000000010000000400000001
2 1 29 test111 test222 0-1-29 0x000000000000000100000005
1 0 16 test test 0-16 0x0000000000000002

(15 行受影响)
东那个升 2010-05-11
  • 打赏
  • 举报
回复
是不是兄弟之间要按ID顺序排列

CREATE TABLE [Department1](
[ID] [bigint] NOT NULL,
[No] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[Name] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[ParentID] [bigint] NULL
)

insert into [Department1]
select 1, 'DNMC', '运营公司', 0 union all
select 7, 'OPS', '生产部', 1 union all
select 8, 'aaaa', 'aaaa', 1 union all
select 9, 'bbbb', 'bbbb', 8 union all
select 10, 'cccc', 'cccc', 8 union all
select 11, 'ddd', 'dddd', 8 union all
select 12, 'vvv', '维修部', 1 union all
select 13, '2233', '技术部', 1 union all
select 14, 'eeee', 'eeee', 7 union all
select 15, 'ffff', 'ffff', 7 union all
select 16, 'test', 'test', 0 union all
select 17, 'rrrrr', 'rrrr', 7 union all
select 18, 'iiii', 'iiii', 10 union all
select 28, '33', '经理室', 13 union all
select 29, 'test111', 'test222', 1

with SubTab as
(
select 1 as [Level],[ParentID],[ID],[No],[Name]
,cast(ltrim(ParentID)+'-'+ltrim(ID) as varchar(max)) as path
,cast(1 as varbinary(max)) as path1
from dbo.Department1
where [ParentID]=0
union all
select b.[Level]+1,a.[ParentID],a.[ID],a.[No],a.[Name]
,b.[Path]+'-'+ltrim(a.[ID])
,path1+CAST(row_number() over(partition by a.[ParentID] order by a.id) as BINARY(4))
from dbo.Department1 a,SubTab b
where a.[ParentID]=b.[ID]
)
select * from SubTab order by [Path1]


Level ParentID ID No Name path path1
----------- -------------------- -------------------- -------------------------------------------------- -------------------------------------------------- ---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
1 0 1 DNMC 运营公司 0-1 0x00000001
1 0 16 test test 0-16 0x00000001
2 1 7 OPS 生产部 0-1-7 0x0000000100000001
2 1 8 aaaa aaaa 0-1-8 0x0000000100000002
2 1 12 vvv 维修部 0-1-12 0x0000000100000003
2 1 13 2233 技术部 0-1-13 0x0000000100000004
2 1 29 test111 test222 0-1-29 0x0000000100000005
3 13 28 33 经理室 0-1-13-28 0x000000010000000400000001
3 8 9 bbbb bbbb 0-1-8-9 0x000000010000000200000001
3 8 10 cccc cccc 0-1-8-10 0x000000010000000200000002
3 8 11 ddd dddd 0-1-8-11 0x000000010000000200000003
4 10 18 iiii iiii 0-1-8-10-18 0x00000001000000020000000200000001
3 7 14 eeee eeee 0-1-7-14 0x000000010000000100000001
3 7 15 ffff ffff 0-1-7-15 0x000000010000000100000002
3 7 17 rrrrr rrrr 0-1-7-17 0x000000010000000100000003

(15 行受影响)
htl258_Tony 2010-05-11
  • 打赏
  • 举报
回复
select top 9 rn=ltrim(row_number()over(order by getdate())),rn_unicode=unicode(ltrim(row_number()over(order by getdate()))) from sysobjects
union all
select '-',unicode('-')
/*
rn rn_unicode
------------------------ -----------
1 49
2 50
3 51
4 52
5 53
6 54
7 55
8 56
9 57
- 45

(10 行受影响)
*/
再看看这个,问题哪里复杂
htl258_Tony 2010-05-11
  • 打赏
  • 举报
回复
select top 9 rn=ltrim(row_number()over(order by getdate())),rn_unicode=unicode(ltrim(row_number()over(order by getdate()))) from sysobjects
union all
select '|',unicode('|')
/*
rn rn_unicode
------------------------ -----------
1 49
2 50
3 51
4 52
5 53
6 54
7 55
8 56
9 57
| 124

(10 行受影响)
*/
麻烦你找一下,哪条不是按照这个规律来排序的。
htl258_Tony 2010-05-11
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 lg3605119 的回复:]
楼上还没看懂我提出问题的本质,不是怎么去正确排序,是因为为什么‘-’变成‘|’就会正常排序,怎么样正确排序我知道,方案我在我发帖的时候已经说得很清楚, 我是要解释为什么‘-’符号会引起此种现象。

CREATE TABLE [Department1](
[ID] [bigint] NOT NULL,
[No] [nvarchar](50) COLLATE Chinese_PRC_C……
[/Quote]你下面的写法排序也不对。主要就是根据排序规则,按照unicode码逐个比较来排序的,没那么复杂。
lg3605119 2010-05-11
  • 打赏
  • 举报
回复
大家帮我找出问题的本质呀 别光顶呀~~
黄_瓜 2010-05-11
  • 打赏
  • 举报
回复
顶小强
lg3605119 2010-05-11
  • 打赏
  • 举报
回复
楼上还没看懂我提出问题的本质,不是怎么去正确排序,是因为为什么‘-’变成‘|’就会正常排序,怎么样正确排序我知道,方案我在我发帖的时候已经说得很清楚, 我是要解释为什么‘-’符号会引起此种现象。

CREATE TABLE [Department1](
[ID] [bigint] NOT NULL,
[No] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[Name] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[ParentID] [bigint] NULL
)

insert into [Department1]
select 1, 'DNMC', '运营公司', 0 union all
select 7, 'OPS', '生产部', 1 union all
select 8, 'aaaa', 'aaaa', 1 union all
select 9, 'bbbb', 'bbbb', 8 union all
select 10, 'cccc', 'cccc', 8 union all
select 11, 'ddd', 'dddd', 8 union all
select 12, 'vvv', '维修部', 1 union all
select 13, '2233', '技术部', 1 union all
select 14, 'eeee', 'eeee', 7 union all
select 15, 'ffff', 'ffff', 7 union all
select 16, 'test', 'test', 0 union all
select 17, 'rrrrr', 'rrrr', 7 union all
select 18, 'iiii', 'iiii', 10 union all
select 28, '33', '经理室', 13 union all
select 29, 'test111', 'test222', 1

;with SubTab([Level],[PID],[ID],[No],[Name],[Path]) as
(
select 1,[ParentID],[ID],[No],[Name],cast(ltrim(ParentID)+'-'+ltrim(ID) as varchar(4000))
from dbo.Department1
where [ParentID]=0
union all
select b.[Level]+1,a.[ParentID],a.[ID],a.[No],a.[Name],cast((b.[Path]+'-'+ltrim(a.[ID])) as varchar(4000))
from dbo.Department1 a,SubTab b
where a.[ParentID]=b.[ID]
)
select * from SubTab order by [Path]
/*
1 0 1 DNMC 运营公司 0-1
2 1 12 vvv 维修部 0-1-12
2 1 13 2233 技术部 0-1-13
3 13 28 33 经理室 0-1-13-28
2 1 29 test111 test222 0-1-29
1 0 16 test test 0-16
2 1 7 OPS 生产部 0-1-7
3 7 14 eeee eeee 0-1-7-14
3 7 15 ffff ffff 0-1-7-15
3 7 17 rrrrr rrrr 0-1-7-17
2 1 8 aaaa aaaa 0-1-8
3 8 10 cccc cccc 0-1-8-10
4 10 18 iiii iiii 0-1-8-10-18
3 8 11 ddd dddd 0-1-8-11
3 8 9 bbbb bbbb 0-1-8-9
*/


;with SubTab([Level],[PID],[ID],[No],[Name],[Path]) as
(
select 1,[ParentID],[ID],[No],[Name],cast(ltrim(ParentID)+'|'+ltrim(ID) as varchar(4000))
from dbo.Department1
where [ParentID]=0
union all
select b.[Level]+1,a.[ParentID],a.[ID],a.[No],a.[Name],cast((b.[Path]+'|'+ltrim(a.[ID])) as varchar(4000))
from dbo.Department1 a,SubTab b
where a.[ParentID]=b.[ID]
)
select * from SubTab order by [Path]
/*
1 0 1 DNMC 运营公司 0|1
2 1 12 vvv 维修部 0|1|12
2 1 13 2233 技术部 0|1|13
3 13 28 33 经理室 0|1|13|28
2 1 29 test111 test222 0|1|29
2 1 7 OPS 生产部 0|1|7
3 7 14 eeee eeee 0|1|7|14
3 7 15 ffff ffff 0|1|7|15
3 7 17 rrrrr rrrr 0|1|7|17
2 1 8 aaaa aaaa 0|1|8
3 8 10 cccc cccc 0|1|8|10
4 10 18 iiii iiii 0|1|8|10|18
3 8 11 ddd dddd 0|1|8|11
3 8 9 bbbb bbbb 0|1|8|9
1 0 16 test test 0|16
*/
htl258_Tony 2010-05-11
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 lg3605119 的回复:]
恩,解决方案很多,但是上面出现的排序问题确实很难解释,大家提出的都是怎么去纠正,并没论证引起排序差异的原因~
[/Quote]
或者前面加n个0,这个需要确认长度,参考10楼永生
htl258_Tony 2010-05-11
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 lg3605119 的回复:]
恩,解决方案很多,但是上面出现的排序问题确实很难解释,大家提出的都是怎么去纠正,并没论证引起排序差异的原因~
[/Quote]
转为二进制码,参考7楼代码
lg3605119 2010-05-11
  • 打赏
  • 举报
回复
恩,解决方案很多,但是上面出现的排序问题确实很难解释,大家提出的都是怎么去纠正,并没论证引起排序差异的原因~
hzvcan 2010-05-11
  • 打赏
  • 举报
回复
if '>'>'0'
begin
select 'yes'
end
else
select 'no'
------
--结果
no
hzvcan 2010-05-11
  • 打赏
  • 举报
回复
-+=>等等好像都有这样的问题
0>1
0>1>12
0>1>13
0>1>13>28
0>1>29
0>1>7
0>1>7>14
0>1>7>15
0>1>7>17
0>1>8
0>1>8>10
0>1>8>10>18
0>1>8>11
0>1>8>9
0>16
--------------------
>的ascii码是62,6的ascii码是54,
所以 0>16 不应该在0>1>8>9前面
hzvcan 2010-05-11
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 lg3605119 的回复:]
我在上面做了个小实验 单纯的看'-'跟数字的ACSII码不能解释上面的现象~~请认真看上面实例的结果
[/Quote]
确实是的
喜-喜 2010-05-04
  • 打赏
  • 举报
回复
看的我晕乎乎的!顶...
feixianxxx 2010-05-04
  • 打赏
  • 举报
回复
IF OBJECT_ID('[tb]') IS NOT NULL
DROP TABLE [tb]
GO
CREATE TABLE [tb] ([col] [nvarchar](10))
INSERT INTO [tb]
SELECT '0-1-5' UNION ALL
SELECT '0-16' union all
select '0-1-6'
go
SELECT * FROM [tb] order by cast(col as BINARY)
/*
col
----------
0-1-5
0-1-6
0-16
*/
Garnett_KG 2010-05-04
  • 打赏
  • 举报
回复
可以用占位符或是合适的COLLATE解决。
htl258_Tony 2010-05-04
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 garnett_kg 的回复:]
排序规则的问题.
[/Quote]KG兄,头像好可怕。
Garnett_KG 2010-05-04
  • 打赏
  • 举报
回复
排序规则的问题.


加载更多回复(10)

27,579

社区成员

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

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