求哪位解答一下这个小问题

沿阶草 2017-11-10 05:43:54
SELECT * FROM (
SELECT '-' AS t
UNION
SELECT '1' AS t
) A
ORDER BY A.t
COLLATE Chinese_PRC_CI_AS


SELECT * FROM (
SELECT '-11' AS t
UNION
SELECT '11' AS t
) A
ORDER BY A.t
COLLATE Chinese_PRC_CI_AS





两个排序出来怎么不一样
不管是按照ASCII完全比较,还是按照排序规则比较,都不应该出现这种结果
那个排序规则是当前默认的排序规则
...全文
376 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
沿阶草 2018-07-20
  • 打赏
  • 举报
回复
继续看这个


SELECT * FROM (
SELECT '-127' AS t
UNION
SELECT '133' AS t
) A
ORDER BY A.t
COLLATE Chinese_PRC_CI_AS
GO
/*
-127
133
*/

SELECT * FROM (
SELECT '-133' AS t
UNION
SELECT '127' AS t
) A
ORDER BY A.t
COLLATE Chinese_PRC_CI_AS
GO
/*
127
-133
*/


SELECT
ASCII('-')+
ASCII('1')+
ASCII('2')+
ASCII('7'),
ASCII('1')+
ASCII('3')+
ASCII('4')
/*
199 152
*/

SELECT
ASCII('-')+
ASCII('1')+
ASCII('3')+
ASCII('4'),
ASCII('1')+
ASCII('2')+
ASCII('7')
/*
197 154
*/

没对齐位数的,按照ASCII和,都应该是位数小的在前面,实际却不是

沿阶草 2018-07-20
  • 打赏
  • 举报
回复
感觉还是不对劲,看下边的例子


SELECT * FROM (
SELECT '-127' AS t
UNION
SELECT '1331' AS t
) A
ORDER BY A.t
COLLATE Chinese_PRC_CI_AS
GO
/*
-127
1331
*/

SELECT * FROM (
SELECT '-133' AS t
UNION
SELECT '1271' AS t
) A
ORDER BY A.t
COLLATE Chinese_PRC_CI_AS
GO
/*
1271
-133
*/

SELECT
ASCII('-')+
ASCII('1')+
ASCII('2')+
ASCII('7'),
ASCII('1')+
ASCII('3')+
ASCII('4')+
ASCII('1')
/*
199 201
*/

SELECT
ASCII('-')+
ASCII('1')+
ASCII('3')+
ASCII('4'),
ASCII('1')+
ASCII('2')+
ASCII('7')+
ASCII('1')
/*
197
203
*/

按照计算的ASCII和两个查询都应该是带-号的值比较小
实际情况却不是
吉普赛的歌 2017-11-14
  • 打赏
  • 举报
回复
引用 5 楼 z10843087 的回复:
确实是,我疏忽了,上面的逻辑只能针对数字当作字符来比较的情况。如果都是字符,是按照顺序来的,就是以第一个字符为准先比较,如果第一个一样再比较第二个 在你的例子中az 中的a 小于bc的b 所以az在前面
SELECT ASCII('1') AS [1],ASCII('2') AS [2],ASCII('3') AS [3],ASCII('9') AS [9]
/*
1    2    3    9
49   50   51   57
*/
 
SELECT * FROM (  
SELECT '23' AS t  
UNION  
SELECT '19' AS t  
) A  
ORDER BY t
/*
1+9=》49+57=106
2+3=》50+51=101

1+9> 2+3
为何 19 还排在上面?

t
19
23
*/ 
数字也不行。 感觉楼主这个问题很意思。
OwenZeng_DBA 2017-11-13
  • 打赏
  • 举报
回复
SELECT * FROM (  
SELECT 'azzzzzzzzzzzz' AS t  
UNION  
SELECT 'baaaaaaa' AS t  
) A  
ORDER BY t 
像这样不管a后面是什么,az始终在前面的
OwenZeng_DBA 2017-11-13
  • 打赏
  • 举报
回复
引用 4 楼 yenange 的回复:
@OwenZeng_DBA http://blog.csdn.net/z10843087/article/details/78516948 拜读了大作, 里面写的比较详细, 但仔细想还是有疑问的: 你的推理只适合这个例子, 再扩展到其它的就不适用了。 比如一个 a 开头的字符串, 一个 b 开头的字符串, b 的后面无论加上什么, 都不可能排序到 a 串的前面。
SELECT ASCII('-') AS [-],ASCII('1') AS [1]
/*
-  1
45 49
*/

SELECT * FROM (  
SELECT '-' AS t  
UNION  
SELECT '1' AS t  
) A  
ORDER BY t
/*
-: 45, 1: 49 , 所以 - 在前 1 在后

-
1
*/

SELECT * FROM (  
SELECT '-11' AS t  
UNION  
SELECT '11' AS t  
) A  
ORDER BY t
/*
45 + 49 + 49 > 49 + 49 , 所以 -11 在后

11
-11
*/

SELECT * FROM (  
SELECT '-11' AS t  
UNION  
SELECT '111' AS t  
) A  
ORDER BY t
/*
45 + 49 + 49 < 49 + 49 + 49

-11
111
*/

SELECT ASCII('a') AS [a],ASCII('b') AS [b],ASCII('c') AS [c],ASCII('z') AS [z]
/*
a    b    c    z
97   98   99   122
*/

SELECT * FROM (  
SELECT 'az' AS t  
UNION  
SELECT 'bc' AS t  
) A  
ORDER BY t 
/*
a+z > b+c , 为何 az 还是排到上面了?

az
bc
*/
确实是,我疏忽了,上面的逻辑只能针对数字当作字符来比较的情况。如果都是字符,是按照顺序来的,就是以第一个字符为准先比较,如果第一个一样再比较第二个 在你的例子中az 中的a 小于bc的b 所以az在前面
吉普赛的歌 2017-11-13
  • 打赏
  • 举报
回复
@OwenZeng_DBA http://blog.csdn.net/z10843087/article/details/78516948 拜读了大作, 里面写的比较详细, 但仔细想还是有疑问的: 你的推理只适合这个例子, 再扩展到其它的就不适用了。 比如一个 a 开头的字符串, 一个 b 开头的字符串, b 的后面无论加上什么, 都不可能排序到 a 串的前面。
SELECT ASCII('-') AS [-],ASCII('1') AS [1]
/*
-  1
45 49
*/

SELECT * FROM (  
SELECT '-' AS t  
UNION  
SELECT '1' AS t  
) A  
ORDER BY t
/*
-: 45, 1: 49 , 所以 - 在前 1 在后

-
1
*/

SELECT * FROM (  
SELECT '-11' AS t  
UNION  
SELECT '11' AS t  
) A  
ORDER BY t
/*
45 + 49 + 49 > 49 + 49 , 所以 -11 在后

11
-11
*/

SELECT * FROM (  
SELECT '-11' AS t  
UNION  
SELECT '111' AS t  
) A  
ORDER BY t
/*
45 + 49 + 49 < 49 + 49 + 49

-11
111
*/

SELECT ASCII('a') AS [a],ASCII('b') AS [b],ASCII('c') AS [c],ASCII('z') AS [z]
/*
a    b    c    z
97   98   99   122
*/

SELECT * FROM (  
SELECT 'az' AS t  
UNION  
SELECT 'bc' AS t  
) A  
ORDER BY t 
/*
a+z > b+c , 为何 az 还是排到上面了?

az
bc
*/
OwenZeng_DBA 2017-11-12
  • 打赏
  • 举报
回复
这个问题其实挺好的,也挺深入的。说说我的理解把。Chinese_PRC_CI_AS 使用的是windows排序规则。它对应的代码是936.也就是GBK的编码。
首先你要明白:在你写这个语句中,他不是按照数字排序的,而是按照字符去排序的。然后我们需要查看字符对应的GBK编码表
参考链接:http://www.qqxiuzi.cn/zh/hanzi-gbk-bianma.php
可以看到-号是在阿拉伯数字1之前的,所有查询出来-在1的前面

而对于下面的查询就涉及多个字符的排序了。他们把这些字符对应的10进制加起来进行比对。然后排序
-11 对应的十进制分别是45 49 49
而11对应的是49 49 ,所以11是小于-11的,自然11就排在-11前面。
下面这个连接可以直接把汉字的转换为对应的16进制或者10 进制,你可以试试
http://www.qqxiuzi.cn/bianma/zifuji.php
日月路明 2017-11-11
  • 打赏
  • 举报
回复
SELECT * FROM ( SELECT '-' AS t UNION SELECT '1' AS t ) A ORDER BY A.t COLLATE Chinese_PRC_CI_AS SELECT * FROM ( SELECT '-11' AS t UNION SELECT '111' AS t ) A ORDER BY A.t COLLATE Chinese_PRC_CI_AS 这样就一样了,不清楚排序规则,但第二个查询字符串长度不一样
  • 打赏
  • 举报
回复
没遇到过,很奇葩也~

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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