跳到主要內容跳到頁尾

QUERY 動態多選:用條件清單篩門市,品名有特殊符號也能查

6 分鐘閱讀摘要與日期

把多個門市放進儲存格清單,用 TEXTJOIN 與 QUERY matches 查詢;遇到加號、括號或引號的品名,改用 SUMPRODUCT 等號判斷與布林輔助欄。說明欄內 OR、欄間 AND、空清單代表全部,以及無符合時只剩表頭的處理。

發布

文章目錄

我想用 QUERY 找「信義或板橋」的銷量,門市名單還會隨時增減。把每個選項放在一個儲存格,再用 TEXTJOIN 接成查詢條件,就不用每次回公式裡改一長串 or。

不過,品名如果叫「A+B」「店(一)」或「O'Reilly」,直接照樣拼進查詢就會踩到符號和引號的問題。這篇先做固定門市清單,再加一欄 TRUE/FALSE,把門市和品名兩份清單一起交給 QUERY 篩。

原始資料與兩份條件清單

下面是刻意保留特殊符號的練習資料,貼到 A1:C9。「A+B」與「AAB」、「店(一)」與「店一」都要當成不同的品名:

門市品項杯數
信義A+B10
信義店(一)20
板橋O'Reilly30
中和AAB40
板橋店一50
中和OReilly60
信義青茶70
板橋青茶拿鐵80

F1 寫「固定門市清單」,H1 寫「任意品項清單」,各選一個名稱就佔一格。先填成這樣,剩下的格子保持空白:

列F:門市清單H:品項清單
2信義A+B
3板橋店(一)
4O'Reilly
5
6

這邊的「多選」是多個儲存格組成的條件清單。讀者可以直接填名稱,或替每格設定一般下拉選單;公式讀的是 F2:F6 與 H2:H6,沒有把多個選項塞進同一格。下拉選單的設定可以看 資料驗證實戰。

先只看門市。信義有 10、20、70 杯,板橋有 30、50、80 杯,手動挑完是 6 筆、260 杯。再加上 H 欄的品項條件,就只剩 A+B 的 10 杯、店(一)的 20 杯、O'Reilly 的 30 杯,共 60 杯。

固定門市:TEXTJOIN 接成 matches 條件

TEXTJOIN 會把多個文字接起來。這次用 | 分隔,F2:F6 的內容就會組成「信義|板橋」,放進 QUERY 的 matches 條件,意思是符合信義或板橋。

在 J1 輸入:

Google 試算表公式
fx

F2:F6 選到的門市,任一間符合就保留

=QUERY( A1:C9, "select A,B,C where A matches '" & IF(COUNTA($F$2:$F$6)=0, ".*", TEXTJOIN("|", TRUE, $F$2:$F$6)) & "'", 1 )

TEXTJOIN 的第二個參數 TRUE 會略過空白儲存格,F4:F6 沒填也沒關係。COUNTA 是計算非空白儲存格個數,整份門市清單都沒填時,就換成 .*,讓這篇的「空選」代表全部門市。

清單有信義、板橋時,查詢文字中的條件會是 A matches '信義|板橋'。最後一個參數 1 則是告訴 QUERY:A1:C9 有一列標題。

來看看結果,J1:L7:

門市品項杯數
信義A+B10
信義店(一)20
板橋O'Reilly30
板橋店一50
信義青茶70
板橋青茶拿鐵80

6 筆、260 杯,原始資料沒有搬動,結果另外列在 J 欄旁邊。QUERY 的選欄與標題列參數若還不熟,可以先看 QUERY 基礎。

matches 的符號會被解讀

這個短寫法適合名稱固定、內容單純的門市選項。matches 讀的是正規表示式,其中 | 表示「或」,其他符號也可能有自己的意思。

我把條件直接改成品名「A+B」試過:

Google 試算表公式
fx

故意保留錯誤:A+B 被當成正規表示式

=QUERY(A1:C9,"select A,B,C where B matches 'A+B'",1)

結果卻是這一筆:

門市品項杯數
中和AAB40

+ 讓前面的 A 重複,抓到的是 AAB,原本要找的「A+B」反而沒進來。括號、句點與直線等符號也有類似的解讀問題;「O'Reilly」還會撞到查詢字串用的單引號。

另外,matches 比的是完整值,且區分英文字母大小寫。它不會自動做「包含這段文字」的搜尋,這點和 contains 不同,詳見 Google 查詢語言說明。

遇到讓人自由填的品名,我個人會把名稱比對搬到輔助欄,查詢字串就不用再處理這些名稱囉。

任意品名:輔助欄先判斷是否命中

回到 F2:F6、H2:H6 的兩份清單。D1 寫「門市且品項命中」,D2 輸入下面這條,再向下複製到 D9:

Google 試算表公式
fx

門市清單內任一項符合,而且品項清單內也有符合項目

=IF( A2="", "", AND( IF(COUNTA($F$2:$F$6)=0, TRUE, SUMPRODUCT(--($F$2:$F$6=A2))>0), IF(COUNTA($H$2:$H$6)=0, TRUE, SUMPRODUCT(--($H$2:$H$6=B2))>0) ) )

看起來長,拆開後每一段做的事很單純:

  • $F$2:$F$6=A2:把這一列的門市,和 F 清單中的每一格逐一比對。
  • --:把比對得到的 TRUE/FALSE 轉成 1/0,SUMPRODUCT 再把它們加起來。
  • 加總大於 0:清單裡至少有一格等於這個門市,就算命中。同一清單內是「或」,也就是 OR。
  • H 清單用同樣的方式比對 B 欄品名;AND 要求兩份清單都命中,所以兩欄之間是「而且」。

兩段 IF(COUNTA(...)=0,TRUE,...) 各自處理空選。門市清單空白就不限門市,品項清單空白就不限品項;最外面的 IF(A2="","",...) 則讓沒有門市的資料列保持空白。

名稱直接用等號比較,「A+B」「店(一)」「O'Reilly」都保留原本的文字,不會再送進查詢字串解讀。

QUERY 只收輔助欄的 TRUE

D 欄算好了,N1 就可以用一條固定的查詢文字取結果:

Google 試算表公式
fx

沒有命中先顯示訊息,有命中才查 D 欄為 TRUE 的資料

=IF( COUNTIF(D2:D9, TRUE)=0, "無符合資料", QUERY(A1:D9, "select A,B,C where D = true", 1) )

COUNTIF 先數 D2:D9 有幾個 TRUE。有符合的列才執行 QUERY,結果只顯示 A、B、C,輔助欄不帶出來。

兩份清單維持開頭的內容時,N1:P4 是:

門市品項杯數
信義A+B10
信義店(一)20
板橋O'Reilly30

共 3 筆、60 杯。這次中和的 AAB 沒有混進來,板橋的「店一」也和「店(一)」分開了。

這一版的 QUERY 文字始終是 select A,B,C where D = true,改的是清單和 D 欄的比對結果。兩邊要一起更新,記得 D 欄必須填滿到最後一筆資料。

無符合時,IFNA 不一定接得到

如果清單裡只有不存在的名稱,直接查詢只會留下「門市/品項/杯數」表頭。外面包 IFNA,也不會換成「無符合資料」,因為這個結果沒有出現錯誤,IFNA 不會觸發。

所以這邊先看 D 欄的 TRUE 個數。沒有任何命中就直接顯示訊息,避免讀的人對著一列表頭猜「是沒資料,還是公式壞了?」其他常見原因整理在 QUERY 進階陷阱。

特殊符號與大小寫的取捨

等號比較不會把 ~、*、?、A|B、A.B、[店]、反斜線這些字元當成特殊符號,都按原樣處理。它們不需要先轉成正規表示式,也不用替引號多接一層引號。

不過,試算表的等號比較不分英文字母大小寫。清單選「Tea」時,「Tea」和「tea」都會命中;如果這兩個名稱在你的資料裡代表不同商品,這一版就不適合直接使用。

兩個版本的取捨可以這樣看:

做法條件內容需要注意
TEXTJOIN 加 matches固定門市清單名稱會被當成正規表示式,並區分英文大小寫
等號輔助欄加 QUERY名稱可能有加號、括號、引號等文字符號按原樣比較,但英文不分大小寫

空選在這篇統一代表「全部」,請讓清單中未使用的儲存格真正保持空白。不要另外填「全部」這個選項,否則等號版會去找名稱真的叫「全部」的資料。

新增資料與清單的位置

這組範例的資料固定到第 9 列,清單固定到第 6 列。新增資料時,要一起擴大 QUERY 的 A1:C9 或 A1:D9、前置檢查的 D2:D9,並把 D 欄公式往下填;新增清單選項超過第 6 列,則要同步擴大公式裡的 F、H 範圍。

J1 與 N1 下方要留給結果展開,先不要放別的資料。想把清單接到圖表、再留幾個控制格給同事操作,可以接著看 互動報表設計。

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

分享:
#QUERY#多選條件#動態清單
喜特先生 Mr. Sheet

喜特先生 Mr. Sheet

數據分析師/商業分析師

八年工作經驗,跨不同業界解決數據需求。做過的案例都整理在作品集。

接下來可以

相關文章

查看所有文章

留言討論

共 0 則留言

訂閱電子報,新文章上線就通知你

免費,隨時可取消。

送出即表示同意服務條款與隱私權政策。