通过


排序

适用于: Databricks SQL 勾选标记为“是” Databricks Runtime 16.1 及更高版本check marked yes

排序规则是一组确定如何进行字符串比较的规则。 排序规则支持不区分大小写、不区分重音和不区分空格的比较,以及语言感知字符串排序。

Azure Databricks中的字符串表示为 UTF-8 编码的 Unicode 字符。 默认情况下,Azure Databricks按二进制 UTF-8 表示形式(称为 UTF8_BINARY排序规则)比较字符串。 UTF8_BINARY 在许多情况下,比较快速且合适,但可能不适合需要语言感知排序或比较的应用程序。

除了二进制比较之外,常见的用例是不区分大小写的匹配。 排序 UTF8_LCASE 规则旨在实现此目的。 在比较 UTF8_BINARY字符串之前,它将字符串转换为小写。

对于语言感知比较,Azure Databricks使用以下技术:

这些技术封装在可用于 SQL 语句的一组命名排序规则中。

注释

有关对 Delta Lake 表使用排序规则时的限制,请参阅“限制”。

排序规则名称

Azure Databricks提供命名的系统排序规则来简化标识。 LDML 规范可能非常复杂,可以直接读取和使用。

语法

{ UTF8_BINARY |
  UTF8_LCASE |
  { UNICODE | locale } [ _ modifier [...] ] }

locale
  language_code [ _ script_code ] [ _ country_code ]

modifier
  { CS | CI | AS | AI | RTRIM }
  • UTF8_BINARY

    一个二进制排序规则,用于基于其 UTF-8 表示形式比较字符串字节字节。 UTF8_BINARY是Azure Databricks中的默认和最轻量级排序规则。

    在此排序规则中: 'A' (x'65') <'B' (x'66') < ... < 'Z' (x'90')。 但是, 'Z' (x'90')'a'<(x'97')和'A'(x'65') <>'a' (x'97')。 字符(如 'Ä' x'C384')大于和 'Z''z'

  • UTF8_LCASE

    一种轻量、不区分大小写的排序规则,用于在比较字符串之前将 UTF8_BINARY字符串转换为小写。

    UTF8_LCASE是用于Azure Databricks中的 Identifiers 的排序规则。

    例如:

    ORDER BY col COLLATE UTF8_LCASE
    

    等效于:

    ORDER BY LOWER(col) COLLATE UTF8_BINARY
    
  • UNICODE

    ICU 根区域设置,在 CLDR root 中称为区域设置(LDML 规范: ) und-u。 此排序规则应用与语言无关的顺序,该顺序将类似字符组合在一起。 例如:'a''Ä'<'b''A'<<. 默认情况下,此排序规则区分大小写和区分重音。

  • locale

    基于 CLDR 表的区域设置感知排序规则。 区域设置被指定为语言代码、可选脚本代码和可选国家/地区代码。 区域设置值不区分大小写。

  • modifier

    控制区分大小写、区分重音和尾随空间行为。 修饰符不区分大小写,可以按任意顺序指定。

    • CS:区分大小写。 默认行为。
    • CI:不区分大小写。
    • AS:区分重音。 默认行为。
    • AI:不区分重音。

    适用于:选中标记为“是” Databricks SQL 选中标记为“是” Databricks Runtime 16.2 及更高版本

    • RTRIM:尾随空间不区分。 比较前剪裁尾随空格(u0020)。

    适用于:选中标记为“是” Databricks SQL 选中标记为“是” Databricks Runtime 16.2 及更高版本

    最多可以指定RTRIM一个CSCI最多指定一个或AI一个AS

Azure Databricks处理排序规则名称时,它会通过删除默认值来规范化名称。 例如, SR_CYR_SRN_CS_AS 规范化为 SR.

有关支持的排序规则的列表,请参阅支持的排序规则

示例

-- Fully qualified collation names are supported; case doesn't matter.
system.builtin.unicode

-- All collations are system-defined and do not require qualification.
unicode

-- Two-letter language code for German collation.
DE

-- Two-letter language code and three-letter country code for French Canadian collation.
fr_CAN

-- Two-letter language code, four-letter script code, and three-letter country code
-- for Traditional Chinese in Macao.
zh_Hant_MAC

-- German collation with case-insensitive and accent-insensitive modifiers.
-- 'Ä', 'A', and 'a' are all considered equal.
de_CI_AI

-- Backticks are allowed but not required for built-in collations.
`UTF8_BINARY`

比较 UTF8_LCASE 和 UNICODE 排序规则

UTF8_LCASE基于 UNICODE 的排序规则(例如UNICODE_CI和支持UNICODE_CI_AI不区分大小写的比较),但它们在处理重音字符和特定于区域设置的规则的方式上有所不同。

行为差异

UTF8_LCASE 将字符串转换为小写,并使用字节对其进行比较 UTF8_BINARY。 它是轻量级且快速的,但将重音字符视为与其不雅形式不同的。

基于 UNICODE 的排序规则使用 ICU 库和 CLDR 区域设置数据。 CIAI修饰符将这一点扩展为等效字符,即使字符在大小写、重音或两者都不同时也是如此。 这些排序规则更彻底,但计算成本更高。

行为 UTF8_LCASE UNICODE_CI UNICODE_CI_AI
'A' = 'a' true true true
'Café' = 'café' true true true
'Cafe' = 'Café' false false true
'ß' = 'ss' (德国锋利) false false false
'resume' = 'résumé' false false true
支持 LIKERLIKE 是的
支持特定于区域设置的规则 是的 是的

何时使用每个排序规则

  • 在重音字符应保持不同时,用于 UTF8_LCASE 快速区分大小写的比较。 此排序规则非常适合从使用简单不区分大小写的字符串匹配的系统进行数据仓库迁移。

  • 用于 UNICODE_CI 遵循 Unicode 规则的不区分大小写的比较,尤其是当数据包含多种语言的字符时,这些语言的简单下限不足。

  • 应忽略大小写和重音差异时使用 UNICODE_CI_AI 。 例如,如果搜索 "resume" 应匹配 "résumé"。 这在面向用户的搜索和多语言应用程序中很常见。

示例

-- UTF8_LCASE lowercases then compares bytes.
-- Accented and unaccented characters are not equivalent.
> SELECT 'Cafe' = 'café' COLLATE UTF8_LCASE;
  false

> SELECT 'Café' = 'café' COLLATE UTF8_LCASE;
  true

-- UNICODE_CI is case-insensitive but accent-sensitive.
-- 'Café' equals 'café' (case differs) but not 'Cafe' (accent differs).
> SELECT 'Café' = 'cafe' COLLATE UNICODE_CI;
  false

> SELECT 'Café' = 'café' COLLATE UNICODE_CI;
  true

-- UNICODE_CI_AI is case-insensitive and accent-insensitive.
-- 'Café' matches 'cafe' because both case and accent differences are ignored.
> SELECT 'Cafe' = 'café' COLLATE UNICODE_CI_AI;
  true

> SELECT 'resume' = 'résumé' COLLATE UNICODE_CI_AI;
  true

-- UTF8_LCASE sorts by lowercase byte order.
-- UNICODE collations sort by linguistic similarity.
> SELECT col FROM VALUES('Banana'), ('apple'), ('Ångström'), ('äpfel') AS t(col)
    ORDER BY col COLLATE UTF8_LCASE;
  apple
  Banana
  Ångström
  äpfel

> SELECT col FROM VALUES('Banana'), ('apple'), ('Ångström'), ('äpfel') AS t(col)
    ORDER BY col COLLATE UNICODE_CI;
  apple
  Ångström
  äpfel
  Banana

默认排序规则

默认排序规则适用于STRING文本、参数标记、没有生成字符串的参数的函数,以及没有STRINGCOLLATE子句的列、字段或变量类型定义。

默认排序规则派生如下:

  • 对于 DDL 语句,例如ALTER TABLECREATE VIEWCREATE TABLE,和CREATE FUNCTION

    • 默认排序规则是正在创建或更改的对象的默认排序规则。
    • 如果没有指定 DEFAULT COLLATION 条款,则默认排序规则为 UTF8_BINARY
  • 对于 DML 语句(UPDATE、、DELETE FROMMERGE INTOINSERT)和查询,默认排序规则为 UTF8_BINARY

排序规则优先级

Azure Databricks应用排序规则优先规则来确定要用于给定字符串的排序规则。 定义了四个优先级别:

  1. 显式

    使用 collate 表达式显式分配排序规则。

    -- Force binary collation to check whether a VIN matches a Ferrari.
    vin COLLATE UTF8_BINARY LIKE 'ZFF%'
    
    -- Force German collation to order German first names.
    ORDER BY vorname COLLATE DE
    
  2. 隐式

    排序规则由 列名称字段名称列别名变量名称参数名称 引用隐式分配,包括排序规则不是 None 的子查询的结果。

    -- Use the collation of the column as defined.
    employee.name LIKE 'Mc%'
    
    -- Use the collation of the variable as defined.
    translate(session.tempvar, 'Z', ',')
    
  3. 默认

    文本 STRING 、命名或未命名 的参数标记,或由另一 STRING 种类型的函数生成的参数标记。

    -- A literal string has the default collation.
    'Hello'
    
    -- :parm1 is a parameter marker using the session default collation.
    EXECUTE IMMEDIATE 'SELECT :parm1' USING 'Hello' AS parm1;
    
    -- ? is a parameter marker using the session default collation.
    EXECUTE IMMEDIATE 'SELECT ?' USING 'Hello';
    
    -- The result of casting a non-STRING to STRING uses the default collation.
    CAST(5 AS STRING)
    
    -- The date is converted to a string using the default collation.
    to_char(DATE'2016-04-08', 'y')
    
    -- session_user() returns a STRING with the default collation.
    session_user()
    

    分配的排序 规则是默认排序规则

  4. STRING函数、运算符或设置操作的结果,例如UNION,该操作采用具有不同隐式排序规则的多个STRING参数。

    -- Concatenating two strings with different explicit collations results in no collation.
    SELECT fr || de AS freutsch FROM VALUES('Voulez vous ' COLLATE FR, 'Kartoffelsupp...' COLLATE DE) AS T(fr, de)
    
    -- A union of two strings with different explicit collations results in no collation.
    SELECT 'Voulez vous ' COLLATE FR UNION ALL SELECT 'Kartoffelsupp...' COLLATE DE
    

排序规则派生

为结果派生排序 STRING 规则时,优先规则按如下所示应用:

  1. 如果表达式与上述定义之一匹配,则排序规则和优先级已定义。

  2. 如果表达式是返回单个STRING参数的函数或运算符STRING,则排序规则和优先级是参数STRING的排序规则和优先级。

  3. 如果表达式是具有两个或多个 STRING 参数的函数或运算符:

    1. 如果所有参数具有相同的排序规则和优先级,则结果使用该排序规则和优先级。

    2. 如果参数具有不同的排序规则或优先级,则让 C1C2 成为不同的排序规则,并 D 成为默认排序规则。 结果由下表确定:

排序规则和优先级 C1 显式 C1 隐式 D 默认
C2 显式 错误 C2 显式 C2 显式 C2 显式
C2 隐式 显式 C1 C2 隐式
D 默认 C1 显式 C1 隐式 D 默认
C1 显式

示例

> SELECT 'hello' = 'hello   ' COLLATE UNICODE_RTRIM;
  true

> CREATE TABLE words(fr STRING COLLATE FR, de STRING COLLATE DE, en STRING COLLATE EN);
> INSERT INTO words VALUES ('Salut', 'Hallo', 'Hello');

-- A literal string has the default collation.
> SELECT collation('Ciao');
  UTF8_BINARY

-- A function producing a STRING has the default collation.
> SELECT collation(user());
  UTF8_BINARY

-- A function that modifies a STRING passes the collation through.
> SELECT collation(upper('Ciao'));
  UTF8_BINARY

-- Implicit collation (French) wins over default collation.
> SELECT collation(fr || 'Ciao') FROM words;
  FR

-- Explicit collation (French) wins over implicit collation (German).
> SELECT collation('Salut' COLLATE FR || de) FROM words;
  FR

-- Implicit German collides with implicit French; the result has no collation.
> SELECT collation(de || fr) FROM words;
  null

-- Explicit collation (French) wins over default collation (Italian).
> SELECT collation('Salut' COLLATE FR || 'Ciao');
  FR

-- Explicit collation (French) collides with explicit collation (German).
> SELECT collation('Salut' COLLATE FR || 'Hallo' COLLATE DE);
  COLLATION_MISMATCH.EXPLICIT

-- Explicit collation wins over no collation.
> SELECT collation('Ciao' COLLATE IT || (fr || de)) FROM words;
  IT

-- Implicit collation (English) does not win over None.
> SELECT collation(en || (fr || de)) FROM words;
  null

-- Explicit collation (English) wins over implicit collation anywhere in the expression.
> SELECT collation((fr || ltrim('H' COLLATE EN, fr)) || fr) FROM words;
  EN

局限性

许多模式匹配和正则表达式函数仅 UTF8_BINARY 支持和 UTF8_LCASE 排序规则。 当这些函数与其他排序规则(如 UNICODE 或区域设置特定的排序规则(如 DEFR_CI_AI)一起使用时,Azure Databricks将引发错误。

受影响的函数包括LIKEILIKERLIKEregexp_*函数系列。 对于与其他排序规则列的字符串匹配,请使用 contains 函数startswith 函数endswith 函数