簡體   English   中英

MySQL用'='選擇UTF-8字符串但不用'LIKE'

[英]MySQL select UTF-8 string with '=' but not with 'LIKE'

我有一張桌子,里面有一些來自中世紀書籍的文字,並且有一些重音字母,在現代拉丁字母表中不再存在。 我可以使用UTF-8組合字符輕松表示這些字母。 例如,要創建一個帶波形符的“J”,我使用UTF-8序列\\ u004A + \\ u0303,J用波浪號重音。

該表使用utf8編碼,字段排序規則為utf8_unicode_ci。

我的問題如下:如果我嘗試選擇整個字符串,我會收到正確的答案。 如果我嘗試選擇使用'LIKE',我會收到錯誤的答案。

例如:

mysql> select word, hex(word) from oldword where word = 'hua';
+--------+--------------+
| word   | hex(word)    |
+--------+--------------+
| hũa    | 6875CC8361   |
| huã    | 6875C3A3     |
| hua    | 687561       |
| hũã    | 6875CC83C3A3 |
+--------+--------------+
4 rows in set (0,04 sec)

mysql> select word, hex(word) from oldword where word like 'hua';
+-------+------------+
| word  | hex(word)  |
+-------+------------+
| huã   | 6875C3A3   |
| hua   | 687561     |
+-------+------------+
2 rows in set (0,04 sec)

我不想只搜索整個單詞。 我想搜索以某些子字符串開頭的單詞。 最終搜索到的單詞是整個單詞。

如何使用like選擇部分字符串並匹配所有字符串?

我嘗試使用此信息創建自定義排序規則,但服務器變得不穩定,只有經過大量試驗和錯誤后,我才能再次恢復到utf8_unicode_ci排序規則並且服務器恢復正常狀態。

編輯:這個網站有問題,一些字符無法正確顯示。 請查看這些pastebins的結果:

http://pastebin.com/mckJTLFX

http://pastebin.com/WP87QvgB

在看到Marcus Adams的回答后,我意識到REPLACE功能可能是解決這個問題的方法,盡管他沒有提到這個功能。

因為我只有兩個不同的組合字符(銳角和波形符號),與其他ASCII字符組合,例如j代表波浪號,j代表尖銳,m代表波浪號,s代表波浪號,等等。 我只需要在使用LIKE時替換這兩個字符。

在查閱手冊后,我了解了UNHEX函數,它幫助我在查詢中正確表示組合字符以刪除它們。

組合波浪號由HEX代碼中的CC83表示, CC83由HEX中的CC81表示。

所以,解決我的問題的查詢就是這個。

SELECT word, REPLACE(REPLACE(word, UNHEX("CC83"), ""), UNHEX("CC81"), "")
FROM oldword WHERE REPLACE(REPLACE(word, UNHEX("CC83"), ""), UNHEX("CC81"), "") 
LIKE 'hua%';`

問題是LIKE逐個字符地執行比較,當使用“組合tilda”時,它實際上是兩個字符,盡管它顯示為一個(假設您的客戶端支持顯示它)。

絕不會有比較哪里的情況下,例如hu~ahua字符一個字符將匹配,因為它比較~a第三字符。

排序(和強制)對你有利,在比較整個字符串時處理這些事情,但在逐個字符比較時則不然。

即使您考慮使用SUBSTRING()作為hack而不是使用LIKE和通配符%來執行前綴搜索,請考慮以下事項:

SELECT SUBSTRING('hũa', 1, 3) = 'hua'
-> 0
SELECT SUBSTRING('hũa', 1, 4) = 'hua'
-> 1

你需要知道你想要的長度或者像這樣蠻力:

SELECT * FROM oldword
WHERE SUBSTRING(word, 1, 3) = 'hua'
   OR SUBSTRING(word, 1, 4) = 'hua'
   OR SUBSTRING(word, 1, 5) = 'hua'
   OR SUBSTRING(word, 1, 6) = 'hua'

根據這個

ũ在5.6的所有utf8排序規則中,整數等於普通U

在大多數校對中, collat​​es等於plain J ; 例外:

  • utf8_general*ci因為它實際上是j加上重音。 並且“常規”排序規則一次只查看一個字符 (區別於字節 )。 大多數排序都會考慮多個字符,例如西班牙語中的chll或德語中的ss
  • utf8_roman_ci ,這是一個非常奇怪的事。 j́=i=j

LIKE並不完全遵循常規的整理規則。我並不精通細節,但我認為J表示為2個字符會導致它在LIKE工作方式與在WHEREORDER BY工作方式不同。此外,我不是知道REPLACE()是否像LIKE或其他地方一樣整理。)

您可以像使用通配符一樣使用%符號。 例如:

SELECT word
FROM myTable
WHERE word LIKE 'hua%';

這將拉出所有以hua開頭且后面跟着0+字符的記錄。 這是一個SQL小提琴示例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM