Sql-Server

以數字為字元串的排序順序

  • April 27, 2022

出於展示目的,我有一個範例表,其中有一varchar列名為numberstring

-4
32
0
4
16
8
-8
1024

在選擇 usingORDER BY numberstring時,我發現不同的使用者得到不同的結果。

一些得到:

-4, -8, 0, 1024, 16, 32, 4, 8

而有些人得到:

0, 1024, 16, 32, -4, 4, -8, 8

不知何故,第二個結果似乎忽略了減號,即使數據以其他方式排序為字元串數據。

據我所知,底層伺服器是 Microsoft SQL Server express 的標準安裝,沒有任何特殊選項。該版本是最近幾年的版本,但使用相同版本的使用者仍然報告不同的結果。

設置中是否存在影響結果的內容,如何從 SSMS 中查看?

據我所知,數據庫伺服器和 SSMS 是在澳大利亞設置的,只有預設值。數據類型是varchar(max)

字元串排序順序由排序規則確定。不同位置的使用者期望數據以不同的方式排序,並且整理將這些期望編碼。

如果未明確指定,列的排序規則是從數據庫/實例級別繼承的。安裝 SQL Server 會設置不同的實例級排序規則,具體取決於使用者選擇的內容或從 Windows 語言設置推斷的預設值。從文件中

伺服器排序規則是在 SQL Server 安裝期間指定的。預設的伺服器級排序規則基於作業系統的區域設置。

例如,使用美國英語 (en-US) 的系統的預設排序規則是SQL_Latin1_General_CP1_CI_AS有關更多資訊,包括 OS 區域設置到預設排序規則映射的列表,請參閱排序規則和 Unicode 支持的“伺服器級排序規則”部分。

您的一些使用者可能預設使用向後兼容的 SQL_Latin1_General_CP1_CI_AS 排序規則,而世界其他地方的其他使用者可能使用類似 Latin1_General_100_CI_AS 的排序規則:

DECLARE @T table 
(
   numberstring varchar(11) COLLATE Latin1_General_100_CI_AS NOT NULL
);

INSERT @T (numberstring) VALUES
('-4'),
('32'),
('0'),
('4'),
('16'),
('8'),
('-8'),
('1024');

SELECT * FROM @T AS T ORDER BY T.numberstring;
DECLARE @T table
(
   numberstring varchar(11) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
);

INSERT @T (numberstring) VALUES
('-4'),
('32'),
('0'),
('4'),
('16'),
('8'),
('-8'),
('1024');

SELECT * FROM @T AS T ORDER BY T.numberstring;

db<>小提琴

這可能是因為您的一些使用者將其 Windows 區域設置設置為*English (United States)*而其他使用者設置為 English (Australia)

在腳本中解決此問題的一種方法是在語句(文件)中使用可選COLLATE子句。CREATE DATABASE


您可以使用以下命令查看每個數據庫的預設排序規則:

SELECT D.[name], D.collation_name 
FROM sys.databases AS D
ORDER BY D.[name];

如果返回 a NULL,則可能是數據庫不線上或由於(對於 SQL Server Express 的AUTO_CLOSE預設設置)而關閉。ON請參閱. _sys.databases

實例級排序規則:

SELECT SERVERPROPERTY('Collation');

較舊的 SQL_* 排序規則對 Unicode 和非 Unicode 數據使用不同的規則:

SELECT FH.* 
FROM sys.fn_helpcollations() AS FH
WHERE FH.[name] IN (N'SQL_Latin1_General_CP1_CI_AS', N'Latin1_General_100_CI_AS');

引用自:https://dba.stackexchange.com/questions/311335