2013年9月25日 星期三

中文排序 (筆劃、部首、拼音)


全球眾多語系,對於排序順序可能因習慣、文化等因素而有所差異,中文常用之排序方法有筆劃、部首、拼音(或注音)等,以下範例列出兩種資料庫中文排序方法。

1.  環境
MSSQL可於伺服器(Server)、資料庫(Database)、資料行(Column)及運算式(Expression)等四個層級進行定序(Collation)設定,ORDEER BY子句是針對特定欄位(群)進行排序,因此須確知排序欄位之定序;ORACLE則支援資料庫及運算式兩種定序設定模式,因此確知資料庫層級之定序設定。MSSQLORACLE查詢指定及結果如下表所示:
#
MSSQL
執行結果
MSSQL
SELECT T.name   Tbl_Name
     , C.name    Col_Name
     , C.collation_name
FROM sys.columns C, sys.tables T
WHERE 1=1
AND T.OBJECT_ID= C.OBJECT_ID
AND T.name = 'CHNTest' --Tbl Name
AND C.name = 'CHN'   --Col Name


ORACLE
SELECT *
FROM v$nls_parameters




2.  中文排序方法
先以中文常用筆劃(Stroke)排序為範例,說明兩種資料庫排序語法,後續再針對兩種資料庫特有排序方法進行說明,SQL及執行結果如下: 
資料庫
SQL
說明
MSSQL
SELECT CHN
FROM CHNTest
ORDER BY CHN COLLATE chinese_taiwan_stroke_cs_as_ks_ws
指定欄位定序為chinese_taiwan_stroke_cs_as_ks_ws
ORACLE
SELECT CHN    
FROM CHNTest
ORDER BY nlssort(CHN,'NLS_SORT=TCHINESE_STROKE_M')
nlssort函數進行轉換

執行結果:(相同)










ORACLE
9i起,針對中文語言方式(Simplified ChineseTraditional Chinese)提供了5種排序方式。如下:
Sort Name
Description
SCHINESE_RADICAL_M
Simplified Chinese sort based on radical as primary order and number of strokes order as secondary order
簡體中文,按照部首(第1順序)、筆劃(第2順序)排序
SCHINESE_STROKE_M
Simplified Chinese sort uses number of strokes as primary order and radical as secondary order
簡體中文,按照筆劃(第1順序)、部首(第二2序)排序
SCHINESE_PINYIN_M
Simplified Chinese PinYin sorting order
簡體中文,按照拼音排序
TCHINESE_RADICAL_M
Traditional Chinese sort based on radical as primary order and number of strokes order as secondary order
正體中文,按照部首(第1順序)、筆劃(第2順序)排序
TCHINESE_STROKE_M
Traditional Chinese sort uses number of strokes as primary order and radical as secondary order. It supports supplementary characters.
正體中文,按照筆劃(第1順序)、部首(第2順序)排序

將先前之測試資料,以本測試環預設之BINARY、筆劃(Stroke)、部首(Radical)及簡中-拼音(Pinyin)共四種方法排序,將進行ROW TO COLUMN轉置以清楚呈現排序結果,後續再探討ROW TO COLUMN概念及作法,無法理解者,可執行中間局部SQLSQL及結果如下。
SELECT SEQ
, MAX(CASE  WHEN SEQ = DFT     THEN CHN END) BINARY
     , MAX(CASE  WHEN SEQ = STROKE  THEN CHN END) STROKE
     , MAX(CASE  WHEN SEQ = RADICAL THEN CHN END) RADICAL
     , MAX(CASE  WHEN SEQ = PINYIN  THEN CHN END) PINYIN       
FROM
  (
   SELECT CHN, DFT, STROKE, RADICAL, PINYIN, SEQ
   FROM
     (
SELECT CHN
  , ROW_NUMBER() OVER (ORDER BY CHN) DFT
  , ROW_NUMBER() OVER (ORDER BY nlssort(CHN,'NLS_SORT=TCHINESE_STROKE_M'))  STROKE
  , ROW_NUMBER() OVER (ORDER BY nlssort(CHN,'NLS_SORT=TCHINESE_RADICAL_M')) RADICAL
  , ROW_NUMBER() OVER (ORDER BY nlssort(CHN,'NLS_SORT=SCHINESE_PINYIN_M'))  PINYIN
FROM CHNTest
     ) A ,
     (
     SELECT LEVEL SEQ
     FROM DUAL
     CONNECT BY LEVEL <=6
     ) N
 )
GROUP BY SEQ










上面測試結果中,BINARY及筆劃排序恰巧相同,此為特例不代表兩者相同,測試時曾發現兩者不同之組合,針對三種方法整理如下:
l   筆劃(Stroke
按照筆劃(第1順序)、部首(第2順序)排序,其中『何』、『杜』筆劃相同,則按部首排序,分別為『人』及『木』。
l   部首(Radical
按照部首(第1順序)、筆劃(第2順序)排序。
l   拼音(Pinyin
按照簡中-拼音(非注音)進行排序,簡中版本僅供參考。

MSSQL
選項
說明
Case sensitivity (CS)
區分大小寫,如Aa視為不同。Case Insensitive(CI)不區分大小寫。
Accent sensitivity (AS)
區分腔調字,如 'a' 不等於 'ấ'Accent Insensitive(AI)則否。
Kana Sensitivity (KS)
區分兩種日文的假名字元Kana Insensitive(KI)則否。
Width sensitivity (WS)
區分全半形 ,如A、A視為不同。Width Insensitive(WI)則視為相同。

以下將列出筆劃(Stroke)及注音(bopomofo)兩種排序方法,SQL及結果如下:
SELECT CHN
     , ROW_NUMBER() OVER (ORDER BY CHN) DFT
     , ROW_NUMBER() OVER (ORDER BY CHN COLLATE Chinese_Taiwan_bopomofo_CS_AS)     bopomofo
     , ROW_NUMBER() OVER (ORDER BY CHN COLLATE chinese_taiwan_stroke_cs_as_ks_ws) Stroke
FROM  CHNTest

結果











MSSQL為支援不同語系而提供為數眾多定序定義,定序可直接由『::fn_helpcollations()』得知定義及說明,SQL如下:
SELECT *
FROM ::fn_helpcollations()
WHERE 1=1
AND name like 'chinese_taiwan%'
AND CHARINDEX('90', name) =0

沒有留言:

張貼留言