我正在寻找一种按 ASCII 排序但不区分大小写的排序规则,但我没有运气找到它。明确地说,我正在寻找的顺序是......
!
"
#
$
%
&
'
(
)
*
+
,
-
.
/
0
1
2
3
4
5
6
7
8
9
:
;
<
=
>
?
@
[
\
]
^
_
`
A
a
B
b
C
c
D
d
E
e
F
f
G
g
H
h
I
i
J
j
K
k
L
l
M
m
N
n
O
o
P
p
Q
q
R
r
S
s
T
t
U
u
V
v
W
w
X
x
Y
y
Z
z
{
|
}
~
这似乎也适合(对于这组字符)Windows 代码页 1252,但我必须承认,我不是代码页专家,可能会读错。 https://en.wikipedia.org/wiki/Windows-1252
我在查询中尝试了多种排序规则来测试它们......
SQL_Latin1_General_CP1_CI_AS
SQL_Latin1_General_CP850_CI_AI
SQL_Latin1_General_CP850_CS_AS
SQL_Latin1_General_CP850_CS_AS
SQL_Latin1_General_CP437_CI_AS
但是他们在这组中都得到了相似的结果,但没有一个是我正在寻找的。一些二进制排序(即
SQL_Latin1_General_CP850_BIN
)很接近,但它们不区分大小写。
我可以通过像...这样的查询来做到这一点
SELECT char_test
FROM code_page_test
ORDER BY ASCII(LOWER (char_test))
但是是否有排序规则设置来获取此排序顺序?
谢谢。
您可以通过创建一个排序字符串来实现此目的,其中每个字符
c
都替换为 LOWER(c) + c
,然后应用 COLLATE Latin1_General_BIN
。这将有效地按 ASCII 顺序对每个字符进行排序,不区分大小写,然后在移动到下一个字符之前将大写字母排序在小写字母前面。
SELECT *
FROM Data D
CROSS APPLY (
SELECT
CASE WHEN D.String IS NOT NULL THEN STRING_AGG(LOWER(c) + c, '') END
COLLATE Latin1_General_BIN
AS SortString
FROM GENERATE_SERIES(1, LEN(D.String)) S
CROSS APPLY(SELECT SUBSTRING(D.String, S.value, 1) AS c) C
) S
ORDER BY S.SortString
IS NULL
检查可防止空字符串与空字符串或空白字符串进行相同的排序。
结果示例:
代码 | 字符串 | 排序字符串 |
---|---|---|
0 | 空 | 空 |
0 | ||
32 | ||
33 | ! | !! |
34 | ” | “” |
35 | # | ## |
... | ... | ... |
47 | / | // |
48 | 0 | 00 |
... | ... | ... |
57 | 9 | 99 |
58 | : | :: |
59 | ; | ;; |
60 | < | << |
... | ... | ... |
96 | ` | `` |
65 | A | aA |
0 | AA | 啊啊啊 |
0 | 啊 | 啊啊啊 |
0 | AB | aAbB |
0 | 抗体 | aAbb |
97 | a | 啊 |
0 | aA | 啊啊啊 |
0 | 啊 | 啊啊啊 |
0 | aB | aabB |
0 | ab | aabb |
66 | B | bB |
0 | BA | bBaA |
0 | 巴 | 咩咩 |
0 | BB | bBbB |
0 | Bb | bBbb |
98 | b | bb |
0 | bA | bbaA |
0 | 巴 | 咩咩 |
0 | bB | bbb |
0 | bb | bbbb |
67 | C | cc |
... | ... | ... |
90 | Z | zZ |
122 | z | zz |
123 | { | {{ |
124 | | | || |
125 | } | }} |
126 | ~ | ~~ |
请参阅 this db<>fiddle 进行演示。