2024-02-15|閱讀時間 ‧ 約 28 分鐘

QUERY 函式大解析(十二):多個 OR 的進階替代寫法——MATCHES +「|」

在用 QUERY 查詢資料時,你曾遇過在 WHERE 寫很多個 OR 的狀況嗎?比如說我們有張表格,上面有各個公司的員工資料:

raw-image

我想用 QUERY 找符合以下條件的員工:

  • 行銷財務網管部門工作
  • 且任職於綠星農業藍星科技

如果用之前提到的 OR 或是 AND,我們可能會這樣寫:

=QUERY(A:F, "SELECT * 
WHERE (B = '行銷' OR B = '財務' OR B = '網管')
AND (F = '綠星農業' OR F = '藍星科技')"
)

不過中間的 OR 有點複雜以外,一直打欄位字母跟單引號也是有點麻煩。所以今天我想要介紹一個進階的做法,MATCHES 和正規表達式的「|」OR 符號來完成。先給大家聞個香:

=QUERY(A:F, "SELECT *
WHERE B MATCHES '行銷|財務|網管'
AND F MATCHES '綠星農業|藍星科技'"
)

是不是簡短有力,一目瞭然呢?

這次我會介紹:

  • 簡單介紹 MATCHES 跟正規表達式
  • 利用 MATCHES 找文字、數字、日期與時間的建議

另外這次會提到的概念會是 WHERE 的延伸,會建議對於 WHERE 有一些了解後再來看看喔!歡迎你來這複習:QUERY 函式大解析(二):WHERE

如果你想看看之前發布過的 QUERY 系列文,可以到這邊找找:QUERY 函式大解析,系列文索引




MATCHES 跟正規表達式是什麼?

按字面解釋,MATCHES 是「符合⋯⋯」的意思。它是 WHERE 的語句中,可以用正規表達式(Regular Expressions)進行搜尋的語法

至於這個「正規表達式」,你可以把它想像成一根要靠咒語發動魔力的魔杖,而它的魔力就是可以幫你搜尋擷取取代資料裡的文字。舉幾個例子:

SELECT * WHERE B MATCHES '.*ia'
SELECT * WHERE C MATCHES '[0-9]+'
SELECT * WHERE D MATCHES '\b[0-9]{2}\b'

MATCHES 後面跟著的那些咒語,就是正規表達式了。🪄

正規表達式的學問很深,但也正因為它能做到非常細緻精準的操作,它不管在程式語言或資料庫搜尋時,應用範圍都相當強大。Google 試算表也有三個函式(REGEXMATCHREGEXEXTRACTREGEXREPLACE)可以讓你用上它,喜特先生預計之後也會正式介紹它們,敬請敲碗期待。

打開這邊的試算表,一起來練習吧!




## MATCHES 'x|y|z|...'

我們這次要用的是正規表達式的眾多咒語中,一個叫做「|」半形 OR 符號的東西,寫起來像是這樣:

WHERE A MATCHES '本田|三菱|日產|馬自達'

意思是「當某資料的 A 欄是本田、三菱、日產或馬自達⋯⋯」

這語法的寫法,基本上就是指定欄位字母後,起一個單引號:

WHERE A MATCHES '

再寫上你想要列舉的項目,並用「|」隔開:

WHERE A MATCHES '本田|三菱|日產|馬自達

最後再用單引號關起來即可。

WHERE A MATCHES '本田|三菱|日產|馬自達'

你也可以搭配 NOT,代表不包含指定的項目。像是尋找不包含「本田、三菱、日產或馬自達」的項目,就可以這樣寫:

WHERE NOT A MATCHES '本田|三菱|日產|馬自達'




練習時間

找文字與數字

先看看「MATCHES 文字與數字」這張工作表。


我們來做文章開頭提到的搜尋條件:

  • 行銷財務網管部門工作
  • 且任職於綠星農業藍星科技

我們在 H2 這邊輸入:

=QUERY(A:F, "SELECT *
WHERE B MATCHES '行銷|財務|網管'
AND F MATCHES '綠星農業|藍星科技'"
)

來看看結果:



來試試看「尋找年齡 20、22、24、26、28 或 30 歲的員工」。這也一樣可以用 MATCHES 來解決。我們在 H23 這邊輸入:

=QUERY(A:F, "SELECT * WHERE C MATCHES '20|22|24|26|28|30'")

來看看結果:

這樣就好了!




找日期

由於 MATCHES 後面只能接正規表達式,沒辦法直接跟日期對接,所以我們需要把日期轉換成數字,讓 MATCHES 起作用。來看看這張表:

這是某客服中心的來電紀錄,B 欄跟 C 欄有日期和時間(以 24 小時制顯示)的資料。


尋找日期為 2024/02/01、2024/02/03、2024/03/05 這三天的資料

因為沒辦法直接拿 B 欄的日期跟 MATCHES 對接,要先做這兩件事:

  • 先透過 DATEVALUE 函式把日期轉換成數字。
  • QUERY 中,再利用 DATEVALUE 把條件裡提到的日期也換成數字,並把文字串連起來。

我們先用 DATEVALUE 把 B 欄的日期轉成數字。在 E2 寫:

=ArrayFormula(DATEVALUE(B2:B))

DATEVALUE 就會幫我們傳回這些數:

再來用 MATCHES 查找 E 欄的值即可。我們在 G2 輸入:

=QUERY(A:E, "SELECT *
WHERE E MATCHES '" &
CONCATENATE(
TEXT("2024/02/01", 0), "|",
TEXT("2024/02/03", 0), "|",
TEXT("2024/03/05", 0))
& "'")

中間這串 CONCATENATE 會把 TEXT 函式轉換好的數字與「|」串起來,就會等同於:

=QUERY(A:E, "SELECT *
WHERE E MATCHES '45323|45325|45356'")

來看看結果:


找時間

說到把時間轉成數字,我們可能會先想到 TIMEVALUE 函式。不過如果以 TIMEVALUE 的方式來做,會因為它容易產生小數點的關係,比較不利於 MATCHES 的查找,會容易失敗。所以我會建議用時間的濾鏡(HOUR()MINUTE()SECOND() 等)跟 MATCHES 搭配就好了!用 ANDOR 也當然沒問題

我們這邊要尋找「上午 12:00、上午 12:15、上午 12:30」這三個時間的資料。你可以看成:

HOUR(C) = 0
MINUTE(C) = 0MINUTE(C) = 15MINUTE(C) = 30

想出來 QUERY 怎麼寫了嗎?沒錯,就是:

=QUERY(A:E, "SELECT * WHERE HOUR(C) = 0 AND MINUTE(C) MATCHES '0|15|30'")


來看看執行結果:


這樣就完成囉!

下次會再提到怎麼用 MATCHES 的「|」搭配 TEXTJOIN 與儲存格範圍連動,讓你的 QUERY 更靈活,敬請期待!




如果你喜歡這次的文章,歡迎你透過這些方法支持我:

  • 按下愛心、按下儲存
  • 留言告訴我你的想法
  • 加入喜特先生的官方沙龍,即時看到我發布的教學
  • 付費訂閱喜特先生的官方沙龍,加入每月小額訂閱方案
  • 追蹤喜特先生的 Facebook
  • 這邊小額贊助我的創作!

想要看更多文章的話,歡迎來到我的 Notion 頁面找找有沒有你需要的資源喔!

我是喜特先生,Mr. Sheet,我們下個教學見!


分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.