為什麼我的 QUERY 沒有報錯,結果卻少了一列?多半是資料欄裡藏了一個文字,或是條件的寫法被 QUERY 另外解讀了。select、where、group by 這些基本寫法在 QUERY 基礎 和 QUERY 分組彙總與月報 講過了,這篇直接從會踩到的地方開始。
後面的例子都用這張訂單,放在 A1:E9。注意 D4 的單價是文字「45元」,是我故意留的:
| 日期 | 品項 | 杯數 | 單價 | 通路 |
|---|---|---|---|---|
| 2026/10/01 | 蘋果紅茶 | 12 | 45 | 店內 |
| 2026/10/02 | 青茶 | 7 | 35 | 外送 |
| 2026/10/03 | 蘋果紅茶 | 5 | 45元 | 外送 |
| 2026/10/05 | 烏龍奶茶 | 9 | 55 | 店內 |
| 2026/10/06 | 青茶 | 14 | 35 | 店內 |
| 2026/10/08 | 蘋果紅茶 | 8 | 45 | 店內 |
| 2026/10/09 | 烏龍奶茶 | 6 | 55 | 外送 |
| 2026/10/10 | 青茶 | 11 | 35 | 店內 |
一欄混了文字,數字就被當成空的
我想找單價 40 以上的訂單,用眼睛掃是 5 筆(45、45、55、45、55)。寫成 QUERY:
單價大於等於 40 的訂單
=QUERY(A1:E9, "select A, B, D where D >= 40", 1)來看看結果:
| 日期 | 品項 | 單價 |
|---|---|---|
| 2026/10/01 | 蘋果紅茶 | 45 |
| 2026/10/05 | 烏龍奶茶 | 55 |
| 2026/10/08 | 蘋果紅茶 | 45 |
| 2026/10/09 | 烏龍奶茶 | 55 |
只有 4 筆,10/03 那筆不見了,而且沒有任何錯誤訊息。QUERY 一次只認一欄裡「佔多數的型別」,這欄 7 個數字、1 個文字,數字佔多數,所以「45元」被當成空值,不符合任何條件。反過來,如果一欄文字佔多數,裡面零星的數字就會消失。
要抓出這種儲存格,我習慣比較 COUNT 和 COUNTA:
得到 7, 得到 8,差的那 1 就是文字。
修法有兩種。資料不多就直接把 D4 改成 45。資料是定期匯入的,我會另外加一欄把文字清乾淨,在 F1 輸入「單價數字」,F2 輸入:
去掉「元」並轉成數字
=ARRAYFORMULA(VALUE(SUBSTITUTE(D2:D9&"", "元", "")))F2:F9 會是 45、35、45、55、35、45、55、35。QUERY 改查 F 欄,範圍也要包含 F:
來看看結果:
| 日期 | 品項 | 單價數字 |
|---|---|---|
| 2026/10/01 | 蘋果紅茶 | 45 |
| 2026/10/03 | 蘋果紅茶 | 45 |
| 2026/10/05 | 烏龍奶茶 | 55 |
| 2026/10/08 | 蘋果紅茶 | 45 |
| 2026/10/09 | 烏龍奶茶 | 55 |
5 筆,跟眼睛掃的一樣。ARRAYFORMULA 的用法在 ARRAYFORMULA 入門。
日期條件:型別要對,儲存格要轉成文字
入門篇講過日期要寫成 date 'yyyy-mm-dd'。這邊看寫錯會怎樣。G1 放 2026/10/05,我想列出這天以後的訂單。
直覺的寫法有兩種。第一種把日期當一般文字比:
日期欄是日期型別,條件卻是文字,兩邊型別不同,結果既不是資料,也不是錯誤:只出現標題列「日期/品項/杯數」,下面一列資料都沒有。第二種直接把 G1 接進去:
儲存格參照接進字串時,拿到的是日期背後的序號,2026/10/05 就是 46300,條件變成 A >= 46300,一樣是日期對數字,一樣只剩標題列,沒有資料也沒有錯誤提示。型別對不上時不報錯,而是「不符合任何一列」,很容易誤以為真的沒有符合的訂單。要先用 TEXT 轉成 yyyy-mm-dd,再補上 date 和單引號:
G1 的日期之後的訂單
=QUERY(A1:E9, "select A, B, C where A >= date '"&TEXT(G1, "yyyy-mm-dd")&"'", 1)來看看結果,5 筆:
| 日期 | 品項 | 杯數 |
|---|---|---|
| 2026/10/05 | 烏龍奶茶 | 9 |
| 2026/10/06 | 青茶 | 14 |
| 2026/10/08 | 蘋果紅茶 | 8 |
| 2026/10/09 | 烏龍奶茶 | 6 |
| 2026/10/10 | 青茶 | 11 |
這串引號最容易看花,我的做法是先把完整的查詢字串放在別的儲存格,看它組出來是不是 ... A >= date '2026-10-05',確定了再丟進 QUERY。
如果日期欄是從別的系統匯出的文字,date 條件對不上,要先轉成真正的日期再查,判斷方式可以看 日期與時間基礎。
用儲存格拼查詢字串:文字加單引號,數字不加
QUERY 沒有可綁定的查詢參數;要把儲存格的值直接寫進查詢文字,就得組合字串。另一種方式是先算布林輔助欄,再查是否命中,後面的文字搜尋與互動報表會說明。G2 放「青茶」,G3 放 10,我想找這個品項、杯數大於等於這個數字的訂單。
漏掉引號:
拼出來是 B = 青茶,沒有引號的文字會被當成欄位名稱,結果是 #VALUE!。文字要夾單引號,數字不用:
品項等於 G2、杯數大於等於 G3
=QUERY(A1:E9, "select A, C where B = '"&G2&"' and C >= "&G3, 1)來看看結果:
| 日期 | 杯數 |
|---|---|
| 2026/10/06 | 14 |
| 2026/10/10 | 11 |
青茶有 3 筆,杯數 7 的那筆不到 10,所以剩 2 筆。
還有兩個小地雷。G3 如果是空白,拼出來是 C >= 後面什麼都沒有,會是語法錯誤。條件的值如果本身有單引號(像 Tom's),單引號會把字串提早結束,這種情況我會直接改用 FILTER,不跟引號搏鬥。
文字搜尋:LIKE 的萬用符,和字面文字不同
這段把方格子的 LIKE、大小寫、WHERE 合成同一個練習,不查姓名或證號。另開空白表,把下列資料貼到 A1;第 13 列 A 欄真的留空,第 14 列則是回傳空字串的公式:
文字 代碼
紅茶 1
青茶 2
烏龍茶 3
奶茶常溫 4
奶茶少冰 5
Taipei 6
TAIPEI 7
taipei 8
50%茶 9
A_B 10
O'茶 11
12
="" 13
École 14
école 15
école 16先在 D1 找「剛好一個字元再加茶」:
LIKE 的底線代表一個字元,不是字面底線
=QUERY(
A1:B17,
"select A,B where A like '_茶'",
1
)結果留下紅茶/1、青茶/2;烏龍茶多一個字,不符合 _茶。% 代表零個或多個字元,所以 %茶% 是前後長度不限、內部有茶;它和 contains '茶' 在這一題的意圖相近,但不是所有樣式都能互換。
沿用 的結構,第二個參數可換成下表的完整查詢文字;每次取代同一個輸出格,或先留出空間:
| 查詢文字 | 預期結果 |
|---|---|
select A,B where A like '%茶%' | 代碼 1、2、3、4、5、9、11 |
select A,B where A starts with '奶' and A ends with '少冰' | 奶茶少冰/5 |
select A,B where A contains '%' | 50%茶/9,找字面的百分比 |
select A,B where A contains '_' | A_B/10,找字面的底線 |
找字面 %、_ 時,直接用 contains 或完全等於,別把它們塞進 like 後又期待不展開,也不要把 SQL 的跳脫寫法直接套過來。
NOT 與空值分開考慮
排除「常溫結尾」時,先寫出非空條件,再否定樣式:
NOT 放在比較條件前,明確排除空值
=QUERY(
A1:B17,
"select A,B where A is not null and not A like '%常溫'",
1
)這個 NOT 例子排除代碼 4、12、13,其餘保留。用 select B where A is null 查詢,真空與公式回傳空字串的兩列都會命中,代碼為 12、13;不要把畫面空白直接當成字面空格,來源若是半形空白字元仍是不同資料。
第三個參數 1 是一列表頭,不是保證「每個沒有資料的查詢都會回錯誤」。只剩表頭時,外層 IFNA 可能接不到;需要顯示查無結果,先另外算命中數,見本篇後段。
大小寫正規化,不改來源
在另一個空白區輸入:
把比較用的文字轉大寫,輸出仍保留原字樣
=QUERY(
A1:B17,
"select A,B where upper(A) = 'TAIPEI'",
1
)結果是 Taipei/6、TAIPEI/7、taipei/8,原欄位並沒有被改成全大寫。upper 是查詢語言的純量函式;放在條件內,不必先改原資料。
把條件改成 upper(A) = 'ÉCOLE',結果是 École/14、école/15,沒有回第 16 筆。第 16 筆是用分解重音字元(e 加組合重音符號 U+0301)組成的 école。外觀接近,不代表底層字元相同;這個案例沒有證明 upper 會做 Unicode 正規化,更不能推成所有語言的大小寫都同一規則。
名稱含單引號:只在可控條件下選另一種引號
本例固定找 O'茶,可以改用雙引號包查詢內的字面文字;CHAR(34) 產生那個雙引號,避免和試算表公式字串本身混淆:
固定的 O 單引號茶,用查詢內雙引號包文字
=QUERY(
A1:B17,
"select A,B where A = "&CHAR(34)&"O'茶"&CHAR(34),
1
)這個固定字串例子只回代碼 11。它不是任意輸入都安全的通用跳脫器:名稱也含雙引號、或把整段條件讓使用者輸入時,仍有語法問題。選單控制可改用 FILTER 或互動報表的布林輔欄,把比較結果交給 QUERY,不直接拼使用者的文字到語法。
文字搜尋練習保留在獨立分頁。接下來的 and/or、彙總與表頭案例,回到開頭的 A1:E9 訂單表。
and 和 or 的括號
我想找「青茶或蘋果紅茶」而且「外送」的訂單,手選是 10/02 青茶和 10/03 蘋果紅茶這 2 筆。照中文的語感寫:
結果是 4 筆:
| 日期 | 品項 | 通路 |
|---|---|---|
| 2026/10/02 | 青茶 | 外送 |
| 2026/10/03 | 蘋果紅茶 | 外送 |
| 2026/10/06 | 青茶 | 店內 |
| 2026/10/10 | 青茶 | 店內 |
多了 2 筆店內的青茶。and 會先於 or 計算,所以這條實際上是「青茶」,或是「蘋果紅茶而且外送」。加上括號才是原本的意思:
括號讓 or 先算
=QUERY(
A1:E9,
"select A, B, E where (B = '青茶' or B = '蘋果紅茶') and E = '外送'",
1
)這次剩下 2 筆:
| 日期 | 品項 | 通路 |
|---|---|---|
| 2026/10/02 | 青茶 | 外送 |
| 2026/10/03 | 蘋果紅茶 | 外送 |
只要同一個 where 裡 and、or 都出現,我就一律加括號,不去背誰先誰後。
彙總不能放進 where
我想找「總杯數超過 20 的品項」。手算蘋果紅茶 12 + 5 + 8 = 25,青茶 7 + 14 + 11 = 32,烏龍奶茶 9 + 6 = 15,答案是青茶和蘋果紅茶。寫成:
結果是 #VALUE!。where 是在分組之前篩每一列,那時候還沒有 sum(C),而這個查詢語言也沒有 SQL 的 having。做法是先分組,再用外層的 QUERY 篩結果:
內層先分組,外層再篩總杯數
=QUERY(
QUERY(A1:E9, "select B, sum(C) group by B label sum(C) '杯數'", 1),
"select Col1, Col2 where Col2 > 20 order by Col2 desc",
1
)來看看結果:
| 品項 | 杯數 |
|---|---|
| 青茶 | 32 |
| 蘋果紅茶 | 25 |
外層的資料是內層 QUERY 的輸出,不是一個普通範圍,所以欄位要寫成 Col1、Col2。下一節會再講這件事。
欄位代號:插欄之後不會跟著改
入門篇講過資料是範圍時用 A、B,是陣列或函式輸出時用 Col1、Col2。這邊補兩個實際會遇到的情況。
第一個是把範圍包進大括號:
大括號組出來的是陣列,沒有欄位字母可用,會是 #N/A,要寫成:
來看看結果:
| 日期 | 杯數 |
|---|---|
| 2026/10/01 | 12 |
| 2026/10/06 | 14 |
| 2026/10/10 | 11 |
第二個是插欄。查詢字串只是一段文字,不是儲存格參照,所以在資料中間插入一欄,範圍會自動變大,字串裡的 C 卻還是原來的 C,指到的就是別的欄,常常是不報錯、只是資料不對。我在資料前面插欄之後,習慣把所有 QUERY 的字串搜尋一遍。想少改幾次,資料就放在最前面一塊,需要新欄位的話加在最右邊。
標題列參數猜錯
第三個參數不填,QUERY 會自己猜標題有幾列。猜錯有兩種樣子。
第一種是範圍沒有標題卻填了 1。範圍是 A2:E9,我想算總杯數,手算是 72:
結果是:
| sum 12 |
|---|
| 60 |
第一筆資料 12 被當成標題,總和少了它,標題變成「sum 12」,看到這種標題就是標題列參數錯了。範圍沒有標題要填 0:
得到 72。上面會多一列標題,只剩函式名稱「sum」加一個空白,因為沒有標題列可以拿來取名。
第二種是不填,由 QUERY 去猜。範圍裡的欄位全部都是文字時,它找不到數字欄可以對照,會把標題當成資料。例如只查 B 欄的品項(欄位代號用的是工作表的字母,所以是 B):
會得到 9,標題「品項」也被數進去了,標題變成只有「count」。加上第三個參數 1 就是 8,標題是「count 品項」。我自己的習慣是只要用 QUERY,第三個參數一定寫出來,不給它猜。
查無資料只剩表頭,IFNA 不一定接得到
QUERY 沒有符合資料時,可能只留下表頭,沒有出現錯誤。這種情況外面包 IFNA 也不會換成提示文字;動態清單的案例就會遇到這個狀況。
如果已經用布林輔助欄判斷每列是否命中,可以先用 COUNTIF 數 TRUE,沒有命中就直接顯示「無符合資料」。完整的清單、加號與引號品名範例,見 QUERY 動態多選,也說明了同一清單內 OR、兩份清單之間 AND 的做法。
練習
找出錯在哪
G1 放 2026/10/03,同事想列出這天以後、通路是外送的訂單,顯示日期、品項、杯數,寫了:
畫面上只出現標題列,一列資料都沒有,也沒有錯誤提示。請說明原因並改正。
遇到 QUERY 的結果怪怪的,先看資料欄有沒有混型別,再看標題列參數,這兩個占了大部分。
我是喜特先生,Mr. Sheet,我們下個教學見!
這個步驟如果每週都要重做
- 現在
- 資料混進「45元」這類文字,要一筆一筆找出來改
- 自動化後
- 匯入時自動清掉單位與空格,異常的列標紅並寄通知給你
接下來可以
相關文章
查看所有文章留言討論
共 0 則留言
