CodeGym /課程 /SQL SELF /陣列比較與過濾:=, @>, <@, &&

陣列比較與過濾:=, @>, <@, &&

SQL SELF
等級 36, 課堂 1
開放

有時候你會遇到這種情境:想知道一組值是不是包含在另一組裡、兩組值有沒有交集、是不是完全一樣,或是某個集合是不是另一個集合的子集合。舉例來說:

  • 使用者有沒有權限進入某些分類?
  • 哪些商品有一樣的標籤?
  • 哪些陣列包含了所有指定的值?

這些問題都可以靠 PostgreSQL 的陣列比較 operator 來解決:=@><@&&。我們會一個一個帶你看,還有實際範例。

= — 陣列相等比較

這個 operator 是用來檢查兩個陣列是不是一模一樣。如果兩個陣列長度一樣、元素順序也一樣,才會回傳 TRUE

範例:

SELECT ARRAY[1, 2, 3] = ARRAY[1, 2, 3] AS are_equal;  -- TRUE
SELECT ARRAY[1, 2, 3] = ARRAY[3, 2, 1] AS are_equal;  -- FALSE

注意:元素順序很重要。[1, 2, 3][3, 2, 1] 不一樣。

@> — 陣列包含另一個陣列

這個 operator 會檢查一個陣列是不是包含另一個陣列的所有元素(順序沒差)。常用在你想確認所有指定元素都有被包含的時候。

範例:

SELECT ARRAY[1, 2, 3] @> ARRAY[1, 2] AS contains;  -- TRUE
SELECT ARRAY[1, 2, 3] @> ARRAY[4] AS contains;     -- FALSE

實用情境:檢查權限。例如你想確定某個角色有沒有包含所有必要的權限。

<@ — 陣列是另一個陣列的子集合

這個 operator 跟 @> 相反。它會檢查一個陣列是不是完全被包含在另一個陣列裡。

範例:

SELECT ARRAY[1, 2] <@ ARRAY[1, 2, 3] AS is_subset;  -- TRUE
SELECT ARRAY[4] <@ ARRAY[1, 2, 3] AS is_subset;     -- FALSE

實用情境:想確認某一筆資料是不是有所有需要的標籤或分類。

&& — 陣列交集

這個 operator 會檢查兩個陣列有沒有至少一個共同的元素。

範例:

SELECT ARRAY[1, 2, 3] && ARRAY[3, 4, 5] AS intersects;  -- TRUE
SELECT ARRAY[1, 2, 3] && ARRAY[6, 7, 8] AS intersects;  -- FALSE

實用情境:找出有共同分類或特性的商品或資料。

在資料過濾時用 operator

來看看怎麼把這些 operator 用在資料表過濾上。假設我們有一個 products 資料表,裡面有個 tags 欄位,存每個商品的標籤陣列。

products 資料表範例

id name tags
1 "Product A" {electronics, sale}
2 "Product B" {home, sale}
3 "Product C" {electronics, new}
4 "Product D" {home, garden}

找出所有有 electronics 標籤的商品。

SELECT *
FROM products
WHERE tags @> ARRAY['electronics'];

結果:

id name tags
1 "Product A" {electronics, sale}
3 "Product C" {electronics, new}

想找標籤剛好是 {home, sale} 的商品。

SELECT *
FROM products
WHERE tags = ARRAY['home', 'sale'];

結果:

id name tags
2 "Product B" {home, sale}

接下來

找出標籤有 {sale, new} 其中一個的商品。
SELECT *
FROM products
WHERE tags && ARRAY['sale', 'new'];

結果:

id name tags
1 "Product A" {electronics, sale}
2 "Product B" {home, sale}
3 "Product C" {electronics, new}

找標籤剛好只有 {home, garden} 的商品。

SELECT *
FROM products
WHERE tags <@ ARRAY['home', 'garden'];

結果:

id name tags
4 "Product D" {home, garden}

範例:用 CASE 判斷陣列內容

我們可以把陣列比較跟條件式結合。比如說,寫個查詢,把有 sale 標籤的商品標記成「有折扣」,其他的標記成「沒折扣」:

SELECT name,
       CASE
         WHEN tags @> ARRAY['sale'] THEN '有折扣'
         ELSE '沒折扣'
       END AS discount_status
FROM products;

結果:

name discount_status
"Product A" 有折扣
"Product B" 有折扣
"Product C" 沒折扣
"Product D" 沒折扣

常見錯誤與避免方式

錯誤:用 = 時忽略元素順序。 記得 = 會檢查順序。如果順序不重要,請用 @>&&

錯誤:資料型態不符。 陣列型態要一樣。像 ARRAY['1', '2']ARRAY[1, 2] 不一樣,一個是字串,一個是數字。比較前一定要確認型態。

錯誤:沒加 index。 如果你常常用陣列來過濾資料,記得加上 GIN index,效能會好很多。

這些 operator 讓你可以很強大地過濾跟比較資料,像商品標籤分析、權限管理這些實務需求都很常見。用得好,查詢又快又簡單,複雜的需求也能輕鬆搞定!

2
任務
SQL SELF, 等級 36, 課堂 1
上鎖
使用 `@>` 運算子檢查陣列內容
使用 `@>` 運算子檢查陣列內容
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION