【问题标题】:Why is apostrophe (') sorted before other ASCII characters?为什么撇号 (') 排在其他 ASCII 字符之前?
【发布时间】:2021-10-26 19:07:59
【问题描述】:

数据库:Azure 专用 SQL 池

排序规则:SQL_Latin1_General_CP1_CI_AS

create table testtable (timeenter nvarchar(30))

insert into testtable values('08:19:21''')
insert into testtable values('08:19:21$')
insert into testtable values('08:19:21%')
insert into testtable values('08:19:21(')
insert into testtable values('08:19:21"')

这是我的问题,当我对值进行排序时,我得到了这个:

select *
from (
    select timeenter
        , ascii(right(timeenter,1)) as ascvalue
        , right(timeenter,1) as symbol
    from testtable 
) x
order by timeenter

结果集:

timeenter                      ascvalue    symbol
------------------------------ ----------- ------
08:19:21'                      39          '
08:19:21"                      34          "
08:19:21$                      36          $
08:19:21%                      37          %
08:19:21(                      40          (

当我使用以下命令订购时:order by timeenter collate Latin1_General_BINorder by timeenter collate SQL_Latin1_General_CP850_BIN,它排序正确:

timeenter                      ascvalue    symbol
------------------------------ ----------- ------
08:19:21"                      34          "
08:19:21$                      36          $
08:19:21%                      37          %
08:19:21'                      39          '
08:19:21(                      40          (

我查找了SQL_Latin1_General_CP1_CI_AS 排序规则,CP1 显示字符集已正确排序,但在我的查询实例中排序顺序仍然不规则。

是不是因为撇号(')是SQL的分隔符?

非常感谢任何见解。

我正在寻找的答案是我的实例如何以及为什么根据当前排序规则对其进行排序。我能够轻松地通过 tsql 以我想要的方式对数据进行排序。根据我的示例,我只是在寻找关于排序规则以及它如何与撇号一起表现的解释。

【问题讨论】:

  • 字符的顺序是由collat​​ion定义的,不是 Ascii值,不同的collat​​ions对字符的排序不同;这是预期的行为。 真正的 问题是,为什么要存储显然是时间的时间,并在其上添加非时间字符 at 后缀,而不是 time 数据类型。
  • @Larnu 谢谢你的回复。数据及其结构源自我继承的旧定制开发系统。它就是这样,并且已经有两年的数据价值没有改变。无论出于何种原因,我之前的人都选择在时间值之后为字符添加后缀,以尝试创建排序顺序。我已经检查了排序规则的排序顺序,但它仍然没有按照排序规则排序。
  • 如果您想根据 ascii 值进行排序,您可以随时使用order by Ascii(Right(timeenter,1))
  • 我至少会将后缀移动到不同的列 @Doua ,然后您就可以拥有强类型数据。 time 列包含您的时间,char 列包含您的后缀。
  • @Stu 谢谢你的回复。我很清楚我可以通过 tsql 更改排序。我希望更多地了解我的排序规则,以及为什么它与撇号一样。我可以通过“符号”对我的查询进行排序,它的行为相同,导致我假设我的排序规则对撇号的处理与二进制排序规则不同。

标签: sql-server tsql collation


【解决方案1】:

这很奇怪。 " ' in SQL_Latin1_General_CP1_CI_AS,如你所见

select case when '''' collate SQL_Latin1_General_CP1_CI_AS < '"' collate SQL_Latin1_General_CP1_CI_AS then 1 else 0 end

输出

0

但如果是unicode字符,则顺序颠倒:

select case when N'''' collate SQL_Latin1_General_CP1_CI_AS < N'"' collate SQL_Latin1_General_CP1_CI_AS then 1 else 0 end

输出

1

【讨论】:

  • 感谢您在我所要求的核心问题上解决我的问题。我看了你的回答几次才意识到答案就在我的脸上盯着我看。这是一个 UNICODE 问题。我的数据类型是问题:NVARCHAR。 nvarchar = unicode 因此排序顺序关闭。如果我用 VARCHAR 重做我的测试表,那么排序就符合我的期望......所以现在我的问题是“排序规则是否忽略数据类型 NVARCHAR?”。
  • 经过一番研究,NVARCHAR 有点像它自己的东西,带有 unicode 数字集。我得到了我想要的教育。再次感谢您!
猜你喜欢
  • 1970-01-01
  • 2015-08-24
  • 2022-11-10
  • 2012-10-11
  • 1970-01-01
  • 1970-01-01
  • 2014-09-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多