CodeGym /課程 /SQL SELF /從陣列取資料: unnest()array_length()

從陣列取資料: unnest()array_length()array_position()

SQL SELF
等級 35 , 課堂 2
開放

操作陣列不只是建立跟存資料而已,很多時候你會需要把單一元素抓出來,或是分析裡面的內容。PostgreSQL 內建了幾個 function 來做這些事,下面我們一個一個來看。

unnest() function:把陣列拆開

unnest() 這個 function 就是把一個陣列拆成一堆 row,每個元素變成一行。這在你想把陣列內容當成 table 來操作時超級有用。

範例 1:簡單拆陣列

假設我們有一個存放學院名稱的陣列:

SELECT ARRAY['資訊學', '數學', '物理'] AS 學院們;

現在要把每個元素都變成一行,用 unnest()

SELECT unnest(ARRAY['資訊學', '數學', '物理']) AS 學院;

結果:

學院
資訊學
數學
物理

範例 2:在 table 裡拆陣列

假設我們有一個 courses table:

CREATE TABLE courses (
    course_id SERIAL PRIMARY KEY,
    course_name TEXT,
    tags TEXT[]
);

INSERT INTO courses (course_name, tags)
VALUES
    ('演算法', ARRAY['程式設計', '資訊學']),
    ('線性代數', ARRAY['數學', '代數']),
    ('物理基礎', ARRAY['物理', '一般']);

現在我們要把所有 tag 從陣列抓出來:

SELECT course_name, unnest(tags) AS tag
FROM courses;

結果:

course_name tag
演算法 程式設計
演算法 資訊學
線性代數 數學
線性代數 代數
物理基礎 物理
物理基礎 一般

你可以看到,陣列裡的每個元素都變成 table 裡的一行。

array_length() function:算陣列長度

第二個很重要的 function 是 array_length(),它會回傳你指定維度的陣列長度(也就是元素個數)。

範例 1:一維陣列的元素數量

來看一個陣列:

SELECT ARRAY['蘋果', '香蕉', '橘子'] AS 水果們;

如果你想知道這個陣列有幾個水果:

SELECT array_length(ARRAY['蘋果', '香蕉', '橘子'], 1) AS 長度;

結果:

長度
3

這裡 1 代表你要查第幾個維度。PostgreSQL 的陣列可以有多維(像是二維陣列),但這裡我們先不討論。

範例 2:查 table 裡陣列的元素數量

來看每個課程有幾個 tag:

SELECT course_name, array_length(tags, 1) AS 標籤數量
FROM courses;

結果:

course_name 標籤數量
演算法 2
線性代數 2
物理基礎 2

這 function 就直接告訴你:「欸,這裡有兩個元素!」這樣分析資料就方便多了。

array_position() function:找陣列裡的值

現在,假設你要在陣列裡找某個特定元素。array_position() 就派上用場了:它會回傳第一次出現這個元素的位置。

範例 1:找元素

假設有個陣列:

SELECT ARRAY['紅色', '藍色', '綠色', '黃色'] AS 顏色們;

來找一下「藍色」的位置:

SELECT array_position(ARRAY['紅色', '藍色', '綠色', '黃色'], '藍色') AS 位置;

結果:

位置
2

如果找不到這個元素,function 會回傳 NULL。來試試看:

SELECT array_position(ARRAY['紅色', '藍色', '綠色', '黃色'], '黑色') AS 位置;

結果:

位置
NULL

範例 2:在 table 陣列裡找元素

你想知道哪個課程有「資訊學」這個 tag。先找出對應的 row:

SELECT course_name, array_position(tags, '資訊學') AS 位置
FROM courses;

結果:

course_name 位置
演算法 2
線性代數 NULL
物理基礎 NULL

再加個條件,只留下有這個 tag 的 row:

SELECT course_name
FROM courses
WHERE array_position(tags, '資訊學') IS NOT NULL;

結果:

course_name
演算法

array_position() 讓你可以很快在陣列裡找到資料,這 function 在 PostgreSQL 處理陣列時超級重要。

function 的實戰應用

  • unnest() — 用來把陣列轉成 row。這對資料分析、報表、處理 tag 都很重要。
  • array_length() — 超適合拿來檢查陣列長度。像是資料驗證時,可以檢查陣列是不是空的。
  • array_position() — 找元素超方便,不管是商品分類、學生參加的專案,還是描述裡的關鍵字都能用。

用 function 時常見的錯誤

  1. unnest() 如果同時對多個 column 的陣列用,row 數可能會變兩倍。這時可以加 JOIN LATERALCROSS JOIN 來解決,但要小心用。
  2. array_length() 對空陣列會回傳 NULL。如果你的陣列可能是空的,記得要另外檢查。
  3. array_position() 找不到元素時會回傳 NULL,所以在 filter 時最好 always 加 IS NOT NULL

真實專案裡的例子

PostgreSQL 的陣列不是只在理論上好用,實際專案也很強大。像你寫 blog,每篇文章有一堆 tag,用陣列存就能很快 filter 出同主題的文章,甚至可以做熱門分類排行榜。

又或者你要分析使用者行為,他們可能會選好幾個有興趣的課程或商品,這些偏好用陣列存起來,處理起來也很方便。

還有,陣列也能幫你驗證資料:用 array_length() 可以限制元素數量,比如不讓使用者選超過五個選項。

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION