

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用純量 Python UDF 設定 Amazon Redshift 查詢結果的語言特定排序
<a name="set-up-language-specific-sorting-for-amazon-redshift-query-results-using-a-scalar-python-udf"></a>

*Ethan Stark，Amazon Web Services*

## 總結
<a name="set-up-language-specific-sorting-for-amazon-redshift-query-results-using-a-scalar-python-udf-summary"></a>

此模式提供使用純量 Python UDF （使用者定義的函數） 設定 Amazon Redshift 查詢結果不區分大小寫語言排序的步驟和範例程式碼。必須使用純量 Python UDF，因為 Amazon Redshift 會根據二進位 UTF-8 排序傳回結果，且不支援語言特定的排序。Python UDF 是非 SQL 處理程式碼，以 Python 程式為基礎，並在資料倉儲中執行。您可以在單一查詢中使用 SQL 陳述式執行 Python UDF 程式碼。如需詳細資訊，請參閱 [Amazon Redshift 大數據部落格文章中的 Python UDFs 簡介](https://aws.amazon.com/blogs/big-data/introduction-to-python-udfs-in-amazon-redshift/) AWS 。

此模式中的範例資料是根據土耳其字母進行示範。此模式中的純量 Python UDF 旨在使 Amazon Redshift 的預設查詢結果符合土耳其文字元的語言順序。如需詳細資訊，請參閱此模式*額外資訊*區段中的*土耳其文語言範例*。您可以針對其他語言，以此模式修改純量 Python UDF。

## 先決條件和限制
<a name="set-up-language-specific-sorting-for-amazon-redshift-query-results-using-a-scalar-python-udf-prereqs"></a>

**先決條件**
+ 具有資料庫、結構描述和資料表的 [Amazon Redshift 叢集](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html) 
+ 具有 `CREATE TABLE`和 `CREATE FUNCTION`許可的 [Amazon Redshift 使用者](https://docs.aws.amazon.com/redshift/latest/dg/r_Users.html) 
+ [Python 2.7](https://www.python.org/download/releases/2.7/) 或更新版本

**限制**

此模式中查詢所使用的語言排序不區分大小寫。

## 工具
<a name="set-up-language-specific-sorting-for-amazon-redshift-query-results-using-a-scalar-python-udf-tools"></a>

**AWS 服務**
+ [Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/gsg/getting-started.html) 是 中的受管 PB 級資料倉儲服務 AWS 雲端。Amazon Redshift 已與您的資料湖整合，可讓您使用資料為您的企業和客戶取得新的洞見。

**其他工具**
+ [Python (UDFs) 使用者定義的函數](https://docs.snowflake.com/en/developer-guide/udf/python/udf-python-introduction.html)是您可以在 Python 中撰寫，然後在 SQL 陳述式中呼叫 的函數。

## 史詩
<a name="set-up-language-specific-sorting-for-amazon-redshift-query-results-using-a-scalar-python-udf-epics"></a>

### 開發程式碼以語言順序排序查詢結果
<a name="develop-code-to-sort-query-results-in-linguistic-order"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 為您的範例資料建立資料表。 | 若要在 Amazon Redshift 中建立資料表並將範例資料插入資料表，請使用下列 SQL 陳述式：<pre>CREATE TABLE my_table (first_name varchar(30));<br /><br />INSERT INTO my_table (first_name)<br />VALUES<br />    ('ali'),<br />    ('Ali'),<br />    ('ırmak'),<br />    ('IRMAK'),<br />    ('irem'),<br />    ('İREM'),<br />    ('oğuz'),<br />    ('OĞUZ'),<br />    ('ömer'),<br />    ('ÖMER'),<br />    ('sedat'),<br />    ('SEDAT'),<br />    ('şule'),</pre>範例資料中的名字包含土耳其字母的特殊字元。如需此範例土耳其文考量事項的詳細資訊，請參閱此模式*額外資訊*區段中的*土耳其文語言範例*。 | 資料工程師 | 
| 檢查範例資料的預設排序。 | 若要在 Amazon Redshift 中查看範例資料的預設排序，請執行下列查詢：<pre>SELECT first_name FROM my_table ORDER BY first_name;</pre>查詢會從您先前建立的資料表傳回名字清單：<pre>first_name<br />---------------<br />Ali<br />IRMAK<br />OĞUZ<br />SEDAT<br />ali<br />irem<br />oğuz<br />sedat<br />ÖMER<br />ömer<br />İREM<br />ırmak<br />ŞULE<br />şule</pre>查詢結果的順序不正確，因為預設的二進位 UTF-8 排序並不符合土耳其文特殊字元的語言順序。 | 資料工程師 | 
| 建立純量 Python UDF。 | 若要建立純量 Python UDF，請使用下列 SQL 程式碼： <pre>CREATE OR REPLACE FUNCTION collate_sort (value varchar) <br />RETURNS varchar <br />IMMUTABLE <br />AS <br />$$    <br />    def sort_str(val):<br />        import string<br />        <br />        dictionary = {<br />            'I': 'ı', <br />            'ı': 'h~', <br />            'İ': 'i', <br />            'Ş': 's~', <br />            'ş': 's~', <br />            'Ğ': 'g~', <br />            'ğ': 'g~', <br />            'Ü': 'u~', <br />            'ü': 'u~', <br />            'Ö': 'o~', <br />            'ö': 'o~', <br />            'Ç': 'c~', <br />            'ç': 'c~'<br />        }<br />        <br />        for key, value in dictionary.items():<br />            val = val.replace(key, value)<br />        <br />        return val.lower()<br /> <br />    return sort_str(value)<br />    <br />$$ LANGUAGE plpythonu;</pre> | 資料工程師 | 
| 查詢範例資料。 | 若要使用 Python UDF 查詢範例資料，請執行下列 SQL 查詢：<pre>SELECT first_name FROM my_table ORDER BY collate_sort(first_name);</pre>查詢現在會以土耳其文語言順序傳回範例資料：<pre>first_name<br />---------------<br />ali<br />Ali<br />ırmak<br />IRMAK<br />irem<br />İREM<br />oğuz<br />OĞUZ<br />ömer<br />Ömer<br />sedat<br />SEDAT<br />şule<br />ŞULE</pre> | 資料工程師 | 

## 相關資源
<a name="set-up-language-specific-sorting-for-amazon-redshift-query-results-using-a-scalar-python-udf-resources"></a>
+ [ORDER BY 子句](https://docs.aws.amazon.com/redshift/latest/dg/r_ORDER_BY_clause.html) (Amazon Redshift 文件）
+ [建立純量 Python UDF ](https://docs.aws.amazon.com/redshift/latest/dg/udf-creating-a-scalar-udf.html)(Amazon Redshift 文件）

## 其他資訊
<a name="set-up-language-specific-sorting-for-amazon-redshift-query-results-using-a-scalar-python-udf-additional"></a>

**土耳其文語言範例**

Amazon Redshift 會根據二進位 UTF-8 排序順序傳回查詢結果，而非特定於語言的排序順序。這表示如果您查詢包含土耳其文字元的 Amazon Redshift 資料表，則查詢結果不會根據土耳其文語言的語言順序排序。土耳其文包含六個特殊字元 (ç、ı、ğ、ö、ş 和 ü)，不會顯示在拉丁字母中。這些特殊字元會根據二進位 UTF-8 順序放置在排序結果集的結尾，如下表所示。


| 
| 
| 二進位 UTF-8 排序 | 土耳其文語言排序 | 
| --- |--- |
| a | a | 
| b | b | 
| c | c | 
| d | **ç (\$1)** | 
| e | d | 
| f | e | 
| g | f | 
| h | g | 
| i | **ğ (\$1)** | 
| j | h | 
| k | **ı (\$1)** | 
| l | i | 
| m | j | 
| n | k | 
| o | l | 
| p | m | 
| r | n | 
| s | o | 
| t | **ö (\$1)** | 
| u | p | 
| v | r | 
| y | s | 
| z | **ş (\$1)** | 
| **ç (\$1)** | t | 
| **ğ (\$1)** | u | 
| **ı (\$1)** | **ü (\$1)** | 
| **ö (\$1)** | v | 
| **ş (\$1)** | y | 
| **ü (\$1)** | z | 

**注意**  
星號 (\$1) 表示土耳其文的特殊字元。

如上表所示，特殊字元 ****ç 在土耳其文語言排序中介於 **c** 和 **d** 之間，但在 **z** 之後以二進位 UTF-8 排序顯示。此模式中的純量 Python UDF 使用下列字元取代字典，以對應的拉丁同等字元取代土耳其文特殊字元。


| 
| 
| 土耳其文特殊字元 | 拉丁文同等角色 | 
| --- |--- |
| ç | c\$1 | 
| ı | h\$1 | 
| ğ | g\$1 | 
| ö | o\$1 | 
| ş | s\$1 | 
| ü | u\$1 | 

**注意**  
波狀符號 (\$1) 字元會附加到取代其對應土耳其文特殊字元的拉丁文字元結尾。

**修改純量 Python UDF 函數**

若要從此模式修改純量 Python UDF 函數，讓函數接受定位參數並支援多個交易字典，請使用下列 SQL 程式碼：

```
CREATE OR REPLACE FUNCTION collate_sort (value varchar, locale varchar) 
RETURNS varchar 
IMMUTABLE 
AS 
$$    
    def sort_str(val):
       import string
       # Turkish Dictionary
       if locale == 'tr-TR':
            dictionary = {
               'I': 'ı', 
               'ı': 'h~', 
               'İ': 'i', 
               'Ş': 's~', 
               'ş': 's~', 
               'Ğ': 'g~', 
               'ğ': 'g~', 
               'Ü': 'u~', 
               'ü': 'u~', 
               'Ö': 'o~', 
               'ö': 'o~', 
               'Ç': 'c~', 
               'ç': 'c~'
        }
        # German Dictionary
        if locale == 'de-DE':
            dictionary = {
               ....
               ....
        }
        
        for key, value in dictionary.items():
            val = val.replace(key, value)
        
        return val.lower()
 
    return sort_str(value)
    
$$ LANGUAGE plpythonu;
```

下列範例程式碼示範如何查詢修改後的 Python UDF：

```
SELECT first_name FROM my_table ORDER BY collate_order(first_name, 'tr-TR');
```