求助一个想不通的地方 关于负号-在sql中varchar类型字段的大小比较中的用法

badiku 2014-04-17 02:30:47
负号 - 有什么特殊意义吗?我看字符中有这个符号时有些诡异

比如


- < 1
3
-a > 1a


a1 < -a2 < a3

这是啥原因?
字符串比较不是逐字符比较的吗?


print @@version

if '-' < '1' print '''-'' < ''1'''
if '-a' < '1a' print '1'
if '-a' = '1a' print '2'
if '-a' > '1a' print '3'
if '-a' > '1a' print '''-a'' > ''1a'''

drop table #test
create table #test (test varchar(20) )
insert #test
select '-1147721273'
union all select '1147721284'
union all select '114772125'
union all select 'a1'
union all select 'a3'
union all select '-a2'
union all select 'a-2'
union all select 'a-4'
union all select 'a4'


select * from #test order by 1




/* 执行结果

Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (X64)
Jul 9 2008 14:17:44
Copyright (c) 1988-2008 Microsoft Corporation
Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) (VM)


'-' < '1'
3
'-a' > '1a'

(9 行受影响)


(1 行受影响)
test
--------------------
114772125
-1147721273
1147721284
a1
-a2
a-2
a3
a4
a-4

(9 行受影响)



(1 行受影响)
*/
...全文
495 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
badiku 2014-04-17
  • 打赏
  • 举报
回复
排序规则的后半部份即后缀 含义: _BIN 二进制排序 _CI(CS) 是否区分大小写,CI不区分,CS区分 _AI(AS) 是否区分重音,AI不区分,AS区分 _KI(KS) 是否区分假名类型,KI不区分,KS区分 _WI(WS) 是否区分宽度 WI不区分,WS区分 区分大小写:如果想让比较将大写字母和小写字母视为不等,请选择该选项。 区分重音:如果想让比较将重音和非重音字母视为不等,请选择该选项。如果选择该选项, 比较还将重音不同的字母视为不等。 区分假名:如果想让比较将片假名和平假名日语音节视为不等,请选择该选项。 区分宽度:如果想让比较将半角字符和全角字符视为不等,请选择该选项 看排序规则的说明 都是和 是否区分大小写 区分重音 区分全角半角 这些相关, 没想到会和 负号 - 相关 真不知道该从何融解 当然知道就行了 不理解也无妨
badiku 2014-04-17
  • 打赏
  • 举报
回复
虽然不明具体原理,但基本上清楚了 a1 < -a2 < a3 这个在中文windows里面 具体来说 在排序规则Chinese_PRC_CI_AS下面 是完全正常的! 说起来这种排序也有一定的合理性 比较人性化 而_BIN二进制那个排序是比较死板。。。
badiku 2014-04-17
  • 打赏
  • 举报
回复
引用 21 楼 sdhp 的回复:
... 我也是偷懒,用默认的,但是遇到问题要知道是怎么回事,怎么解决,所以具体解决方法还要看你的需求。 比如我司有一个表中某数据是区分大小写的,且是PK,所以就要把那一列改为CS_AI
说来也是 平时偷懒习惯了。遇到问题了再来到处找原因。。。谢谢你啊
闹铃 2014-04-17
  • 打赏
  • 举报
回复
引用 18 楼 badiku 的回复:
本来我以为这是和操作系统有关 但我找了个 windows2003 windows2008 win8 ,分别试了一下,都是同样的结果。 这是sql server中文版的默认设置啊,真的很奇怪别的人从没遇到这个问题? 还是大家搞sql的都知道这个?都在设计数据库或写每一个sql时都指定一下排序规则?
设置了数据库的排序规则
sdhp 2014-04-17
  • 打赏
  • 举报
回复
引用 17 楼 badiku 的回复:
[quote=引用 14 楼 sdhp 的回复:] ... 你可以在建表的时候就指定排序规则,比如: create table #test (test varchar(20) collate Chinese_PRC_BIN) 以后这一列再遇到这种情况的时候不需要指定排序规则也会按照建表时的排序规则来做比较、排序
好像你这个规则不常用吧? 我刚才仔细查了下 确实有个规则 是Chinese_PRC_CI_AS 但这是所有中文sql server的默认排序规则吧? 排序规则的后半部份即后缀含义:    _BIN 二进制排序   _CI(CS) 是否区分大小写,CI不区分,CS区分    _AI(AS) 是否区分重音,AI不区分,AS区分   就是说 如果要完全用所谓的逐字母比较,就相当于用 _BIN 二进制排序。 如果用系统默认的 Chinese_PRC_CI_AS 那就只能是我上面那个诡异的结果了? 那你们平时建库时都是指定了 _BIN 二进制排序的? 我个人感觉用默认排序的还是比较多的(偷懒 ) 是不是如果是用默认[/quote] 我也是偷懒,用默认的,但是遇到问题要知道是怎么回事,怎么解决,所以具体解决方法还要看你的需求。 比如我司有一个表中某数据是区分大小写的,且是PK,所以就要把那一列改为CS_AI
闹铃 2014-04-17
  • 打赏
  • 举报
回复
sql 联机帮助中 “使用排序规则” 。有详细的说明, Chinese_PRC_CI_AS 这个是默认的 我的本地也是。用这个排序规则也会出现你刚才的情况。
badiku 2014-04-17
  • 打赏
  • 举报
回复
本来我以为这是和操作系统有关 但我找了个 windows2003 windows2008 win8 ,分别试了一下,都是同样的结果。 这是sql server中文版的默认设置啊,真的很奇怪别的人从没遇到这个问题? 还是大家搞sql的都知道这个?都在设计数据库或写每一个sql时都指定一下排序规则?
badiku 2014-04-17
  • 打赏
  • 举报
回复
引用 14 楼 sdhp 的回复:
... 你可以在建表的时候就指定排序规则,比如: create table #test (test varchar(20) collate Chinese_PRC_BIN) 以后这一列再遇到这种情况的时候不需要指定排序规则也会按照建表时的排序规则来做比较、排序
好像你这个规则不常用吧? 我刚才仔细查了下 确实有个规则 是Chinese_PRC_CI_AS 但这是所有中文sql server的默认排序规则吧? 排序规则的后半部份即后缀含义:    _BIN 二进制排序   _CI(CS) 是否区分大小写,CI不区分,CS区分    _AI(AS) 是否区分重音,AI不区分,AS区分   就是说 如果要完全用所谓的逐字母比较,就相当于用 _BIN 二进制排序。 如果用系统默认的 Chinese_PRC_CI_AS 那就只能是我上面那个诡异的结果了? 那你们平时建库时都是指定了 _BIN 二进制排序的? 我个人感觉用默认排序的还是比较多的(偷懒 ) 是不是如果是用默认
闹铃 2014-04-17
  • 打赏
  • 举报
回复
排序规则影响所有与字符串比较相关的语句,包括各种排序(GROUP BY/PARTITION BY/ORDER BY)、索引内部存储、字符串的比较(=、>、>=、<、<=、<>、LIKE)。特别需要强调的是,LIKE字符串匹配中的范围如'[A-Z]',也依赖于指定的排序规则。
闹铃 2014-04-17
  • 打赏
  • 举报
回复
引用 13 楼 badiku 的回复:
[quote=引用 11 楼 denghui_li 的回复:] ... 有可能跟排序规则有关, 我的是:SQL_Latin1_General_CP1_CI_AS
都说是什么 排序规则 难道您们平时写sql时都每个语句接一个 排序规则 ? 我平时真的没注意过这个 [/quote] 查看一下你的排序 规则 是什么 select SERVERPROPERTY('Collation') 我不确定它会不会影响 字符的ascii 值,之前没遇到过
sdhp 2014-04-17
  • 打赏
  • 举报
回复
引用 12 楼 badiku 的回复:
[quote=引用 9 楼 sdhp 的回复:] 我觉得和排序规则collate有关 你改用排序规则collate Chinese_PRC_BIN试试看: ...
排序规则? 这个倒是从没管过 反正是个中文windows,没留意过这个。试一下先[/quote] 你可以在建表的时候就指定排序规则,比如: create table #test (test varchar(20) collate Chinese_PRC_BIN) 以后这一列再遇到这种情况的时候不需要指定排序规则也会按照建表时的排序规则来做比较、排序
badiku 2014-04-17
  • 打赏
  • 举报
回复
引用 11 楼 denghui_li 的回复:
... 有可能跟排序规则有关, 我的是:SQL_Latin1_General_CP1_CI_AS
都说是什么 排序规则 难道您们平时写sql时都每个语句接一个 排序规则 ? 我平时真的没注意过这个
badiku 2014-04-17
  • 打赏
  • 举报
回复
引用 9 楼 sdhp 的回复:
我觉得和排序规则collate有关 你改用排序规则collate Chinese_PRC_BIN试试看: ...
排序规则? 这个倒是从没管过 反正是个中文windows,没留意过这个。试一下先
闹铃 2014-04-17
  • 打赏
  • 举报
回复
/*------------------------ select * from #test where test between 'a1' and 'a4'; ------------------------*/ test -------------------- a1 a3 a4 (3 行受影响) 有可能跟排序规则有关, 我的是:SQL_Latin1_General_CP1_CI_AS
闹铃 2014-04-17
  • 打赏
  • 举报
回复
引用 4 楼 badiku 的回复:
字符串比较 我的理解是从首字符起 逐字符比较 如 abc < abd abc < acc 但这个-太诡异了 a1 < -a2 < a3 从a1 < -a2 来看 首字符 a < - 从-a2 < a3 来看 首字符 - < a 完全是自相矛盾啊
/*------------------------ if 'a1' < '-a2' and '-a2' < 'a3' print 'YES (a1 < -a2 < a3)'; else print 'NO (a1 < -a2 < a3)' ------------------------*/ NO (a1 < -a2 < a3)
sdhp 2014-04-17
  • 打赏
  • 举报
回复
我觉得和排序规则collate有关 你改用排序规则collate Chinese_PRC_BIN试试看:

with t as(
select '-1147721273' collate Chinese_PRC_BIN as col1
    union all select  '1147721284'
    union all select  '114772125'
    union all select  'a1'
    union all select  'a3'
    union all select  '-a2'
    union all select  'a-2'
    union all select  'a-4'
    union all select  'a4')
 select col1 from t order by col1
badiku 2014-04-17
  • 打赏
  • 举报
回复
引用 5 楼 denghui_li 的回复:
你想说什么?
我觉得我还是说得比较清楚了,而且上面我举出了详细的sql测试语句。 如果您有兴趣的话 不妨试一下 一分钟的时间而已 举手之劳 谢谢
badiku 2014-04-17
  • 打赏
  • 举报
回复
引用 5 楼 denghui_li 的回复:
你想说什么?
没看明白? 比如上面我例那个临时表 我现在想找 值界于 a1和a4之间的 select * from #test where test between 'a1' and 'a4' order by 1 结果是 a1 -a2 a-2 a3 a4 那个 -a2 就是属于异常结果, 不能包含在结果里面的!
badiku 2014-04-17
  • 打赏
  • 举报
回复
引用 5 楼 denghui_li 的回复:
你想说什么?
没看明白? 从a1 < -a2 来看 首字符 a < - 从-a2 < a3 来看 首字符 - < a 完全是自相矛盾啊 这样在有些时候想按某个标准进行查询时就会引起混乱
闹铃 2014-04-17
  • 打赏
  • 举报
回复
你想说什么?
加载更多回复(4)

34,593

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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