在用 QUERY
查詢資料時,你曾遇過在 WHERE
寫很多個 OR
的狀況嗎?比如說我們有張表格,上面有各個公司的員工資料:
我想用 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
是「符合⋯⋯」的意思。它是 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 試算表也有三個函式(REGEXMATCH
、REGEXEXTRACT
、REGEXREPLACE
)可以讓你用上它,喜特先生預計之後也會正式介紹它們,敬請敲碗期待。
打開這邊的試算表,一起來練習吧!
我們這次要用的是正規表達式的眾多咒語中,一個叫做「|
」半形 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
搭配就好了!用 AND
、OR
也當然沒問題。
我們這邊要尋找「上午 12:00、上午 12:15、上午 12:30」這三個時間的資料。你可以看成:
HOUR(C) = 0
MINUTE(C) = 0 或 MINUTE(C) = 15 或 MINUTE(C) = 30
想出來 QUERY
怎麼寫了嗎?沒錯,就是:
=QUERY(A:E, "SELECT * WHERE HOUR(C) = 0 AND MINUTE(C) MATCHES '0|15|30'")
來看看執行結果:
這樣就完成囉!
下次會再提到怎麼用 MATCHES
的「|
」搭配 TEXTJOIN
與儲存格範圍連動,讓你的 QUERY
更靈活,敬請期待!
如果你喜歡這次的文章,歡迎你透過這些方法支持我:
想要看更多文章的話,歡迎來到我的 Notion 頁面找找有沒有你需要的資源喔!
我是喜特先生,Mr. Sheet,我們下個教學見!