1. 程式人生 > 資料庫 >MySQL資料型別 - JSON資料型別 (4)

MySQL資料型別 - JSON資料型別 (4)

JSON值的比較和排序

JSON值可以使用=,<,<=,>,>=,<>,!=,和<=>運算子進行比較。

JSON值尚不支援以下比較運算子和函式:

●BETWEEN

●IN()

●GREATEST()

●LEAST()

要想使用上面這些列出的比較運算子和函式,一個解決方法是將JSON值轉換為原生MySQL數值或字串資料型別,以便它們具有一致的非JSON標量型別。

JSON值的比較在兩個級別進行。第一級比較基於所比較值的JSON型別。如果型別不同,則比較結果僅由哪個型別具有更高的優先順序來確定。如果這兩個值具有相同的JSON型別,則使用特定於型別的規則進行第二級比較。

下面的列表顯示了JSON型別的優先順序,從最高優先順序到最低優先順序。(型別名是由JSON_TYPE()函式返回的型別)同一行中顯示的型別具有相同的優先順序。列表中前面列出的JSON型別的值都比列表中後面列出的JSON型別的值大。

MySQL資料型別 - JSON資料型別 (4)

對於具有相同優先順序的JSON值,比較規則是依據於特定型別的:

●BLOB

比較兩個值的前N個位元組,其中N是較短值的位元組數。如果兩個值的前N個位元組相同,則短值排在長值之前。

●BIT

與BLOB規則相同。

●OPAQUE

與BLOB規則相同。OPAQUE值是指不屬於其他型別的值。

●DATETIME

表示較早時間點的值排在表示稍後時間點的值之前。如果兩個值最初分別來自MySQL DATETIME和TIMESTAMP型別,那麼如果它們表示相同的時間點,那麼它們是相等的。

●TIME

兩個時間值中較小的一個排在較大的時間值之前。

●DATE

較早的日期排在較近的日期之前。

●ARRAY

如果兩個JSON陣列的長度相同,並且陣列中相應位置的值相等,則它們是相等的。

如果陣列不相等,則它們的順序由第一個位置有差異的元素決定。該位置值較小的陣列排在前面。如果較短陣列的所有值都等於較長陣列中的相應值,則較短陣列排在前面。

例子:

MySQL資料型別 - JSON資料型別 (4)
●BOOLEAN

JSON false字面量小於JSON true字面量。

●OBJECT

如果兩個JSON物件具有相同的鍵集,並且每個鍵在兩個物件中都具有相同的值,那麼它們是相等的。

例子:
MySQL資料型別 - JSON資料型別 (4)

●STRING

兩個字串比較前N個位元組,這些位元組以utf8mb4編碼表示,並按照字典順序排列,其中N是較短字串的長度。如果兩個字串的前N個位元組相同,則認為較短的字串比較長的字串小。

例子:

MySQL資料型別 - JSON資料型別 (4)

此排序相當於使用排序規則utf8mb4_bin對SQL字串進行排序。由於utf8mb4_bin是二進位制排序規則,因此JSON值的比較區分大小寫:

MySQL資料型別 - JSON資料型別 (4)

●INTEGER, DOUBLE

JSON值可以包含精確的數值和近似的數值。

在JSON值中比較數字的規則與原生MySQL數值型別的比較規則有些不同:

■ 在分別使用原生MySQL INT和DOUBLE 數字型別的兩個列之間的比較中,所有比較都涉及一個整數和一個雙精度型別,因此所有行,整數都轉換為雙精度型別。也就是說,精確的數值被轉換成近似的數值。

■ 另一方面,如果查詢比較兩個包含數字的JSON列,則無法預先知道數字是整數還是雙精度。為了在所有行中提供最一致的行為,MySQL將近似值數字轉換為精確值數字。結果排序是一致的,並且精確值不會丟失精度。例如,給定標量9223372036854775805、9223372036854775806、9223372036854775807和9.223372036854776e18,順序如下:

MySQL資料型別 - JSON資料型別 (4)

如果JSON比較使用非JSON數值比較規則,則可能會出現順序不一致的情況。通常的MySQL數字比較規則會產生以下順序:

■ 整數比較:
MySQL資料型別 - JSON資料型別 (4)

■ 雙精度比較:

MySQL資料型別 - JSON資料型別 (4)

對於任何JSON值與SQL NULL的比較,結果是未知的。

為了比較JSON和非JSON值,非JSON值根據下表的規則轉換為JSON,然後按照前面的描述進行比較。

在JSON和非JSON值之間的轉換

下表彙總了MySQL在JSON值和其他型別值之間轉換時遵循的規則:

MySQL資料型別 - JSON資料型別 (4)

JSON值的ORDER BY和GROUP BY處理基於以下原則:

●標量JSON值的排序使用與前面討論中相同的規則。

●對於升序排序,SQL NULL順序在所有JSON值(包括JSON null字面量)之前;對於降序排序,SQL NULL順序位於所有JSON值(包括JSON null字面量)之後。

●JSON值的排序鍵由max_sort_length系統變數的值繫結,因此第一個max_sort_length位元組相同,之後才不同的鍵被認定為相等。

●當前不支援對非標量值進行排序,會出現警告。

對於排序,將JSON標量轉換為其他一些原生MySQL型別是有益的。例如,如果名為jdoc的列包含JSON物件,該物件有一個成員由id鍵和非負值組成,則使用此表示式按id值排序:

MySQL資料型別 - JSON資料型別 (4)

如果有一個生成的列被定義為使用與ORDER BY中相同的表示式,MySQL優化器會識別出這一點,並考慮將索引用於查詢執行計劃。

JSON值聚合

對於JSON值的聚合,SQL NULL值被忽略,就像在其他資料型別中一樣。非NULL值將轉換為數值型別並進行聚合,但MIN()、MAX()和GROUP_CONCAT()除外。如果JSON的值是數值標量,轉換成數字是有意義,儘管(取決於值)可能會發生截斷和精度損失。其他JSON值轉換成數量可能不會產生有意義的結果。

官方文件地址: