我想用 QUERY 找「信義或板橋」的銷量,門市名單還會隨時增減。把每個選項放在一個儲存格,再用 TEXTJOIN 接成查詢條件,就不用每次回公式裡改一長串 or。
不過,品名如果叫「A+B」「店(一)」或「O'Reilly」,直接照樣拼進查詢就會踩到符號和引號的問題。這篇先做固定門市清單,再加一欄 TRUE/FALSE,把門市和品名兩份清單一起交給 QUERY 篩。
原始資料與兩份條件清單
下面是刻意保留特殊符號的練習資料,貼到 A1:C9。「A+B」與「AAB」、「店(一)」與「店一」都要當成不同的品名:
| 門市 | 品項 | 杯數 |
|---|---|---|
| 信義 | A+B | 10 |
| 信義 | 店(一) | 20 |
| 板橋 | O'Reilly | 30 |
| 中和 | AAB | 40 |
| 板橋 | 店一 | 50 |
| 中和 | OReilly | 60 |
| 信義 | 青茶 | 70 |
| 板橋 | 青茶拿鐵 | 80 |
F1 寫「固定門市清單」,H1 寫「任意品項清單」,各選一個名稱就佔一格。先填成這樣,剩下的格子保持空白:
| 列 | F:門市清單 | H:品項清單 |
|---|---|---|
| 2 | 信義 | A+B |
| 3 | 板橋 | 店(一) |
| 4 | O'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 輸入:
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+B | 10 |
| 信義 | 店(一) | 20 |
| 板橋 | O'Reilly | 30 |
| 板橋 | 店一 | 50 |
| 信義 | 青茶 | 70 |
| 板橋 | 青茶拿鐵 | 80 |
6 筆、260 杯,原始資料沒有搬動,結果另外列在 J 欄旁邊。QUERY 的選欄與標題列參數若還不熟,可以先看 QUERY 基礎。
matches 的符號會被解讀
這個短寫法適合名稱固定、內容單純的門市選項。matches 讀的是正規表示式,其中 | 表示「或」,其他符號也可能有自己的意思。
我把條件直接改成品名「A+B」試過:
故意保留錯誤:A+B 被當成正規表示式
=QUERY(A1:C9,"select A,B,C where B matches 'A+B'",1)結果卻是這一筆:
| 門市 | 品項 | 杯數 |
|---|---|---|
| 中和 | AAB | 40 |
+ 讓前面的 A 重複,抓到的是 AAB,原本要找的「A+B」反而沒進來。括號、句點與直線等符號也有類似的解讀問題;「O'Reilly」還會撞到查詢字串用的單引號。
另外,matches 比的是完整值,且區分英文字母大小寫。它不會自動做「包含這段文字」的搜尋,這點和 contains 不同,詳見 Google 查詢語言說明。
遇到讓人自由填的品名,我個人會把名稱比對搬到輔助欄,查詢字串就不用再處理這些名稱囉。
任意品名:輔助欄先判斷是否命中
回到 F2:F6、H2:H6 的兩份清單。D1 寫「門市且品項命中」,D2 輸入下面這條,再向下複製到 D9:
門市清單內任一項符合,而且品項清單內也有符合項目
=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 就可以用一條固定的查詢文字取結果:
沒有命中先顯示訊息,有命中才查 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+B | 10 |
| 信義 | 店(一) | 20 |
| 板橋 | O'Reilly | 30 |
共 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 基礎:select、where、order by、limit 四句就能查資料
從一張訂單表開始,學 QUERY 的查詢語言:select 選欄位、where 設條件、order by 排序、limit 取前幾筆,以及欄位代號 A、B 與 Col1 的差別、文字條件的引號和 headers 參數。
QUERY 少了幾列、日期比不出來、括號算錯的原因與修法
整理 QUERY 不報錯卻給錯結果的情況:一欄混了文字、日期條件與儲存格拼接、文字與數字的引號、and 與 or 的括號、彙總不能放進 where、插欄後的欄位字母、標題列參數猜錯。
互動式報表設計:用下拉選單和核取方塊讓同一張報表自己換內容
把門市銷量表做成讀的人自己操作的報表:控制格放下拉選單與核取方塊,用 TEXTJOIN 與 SWITCH 把選擇組成 QUERY 字串,再比較 FILTER、QUERY 與切片器各自適合的場合,以及怎麼只開放控制格給別人改。
留言討論
共 0 則留言
