スプレッドシートでQuery関数を使ってデータを引っ張ってくるときに以下のようなエラーが発生しました。
関数 QUERY のパラメータ 2 のクエリ文字列を解析できません。PARSE_ERROR: Encountered ” “by” “BY “” at line ~
ここではこのエラーの原因と対処法について解説しています。
エラーの詳細
エラーの内容
今回発生したエラーは以下のようなものです。
エラー関数 QUERY のパラメータ 2 のクエリ文字列を解析できません。PARSE_ERROR: Encountered ” “by” “BY “” at line 1, column 176. Was expecting one of: “true” … “false” … “date” … “timeofday” … “datetime” … “timestamp” … “min” … “max” … “avg” … “count” … “sum” … “no_values” … “no_format” … “is” … “null” … “year” … “month” … “day” … “hour” … “minute” … “second” … “millisecond” … “with” … “contains” … “starts” … “ends” … “matches” … “like” … “now” … “dateDiff” … “quarter” … “lower” … “upper” … “dayOfWeek” … “toDate” … <ID> … <INTEGER_LITERAL> … <DECIMAL_LITERAL> … <STRING_LITERAL> … <QUOTED_ID> … “(” … “-” … “min” … “max” … “count” … “avg” … “sum” … “year” … “month” … “day” … “hour” … “minute” … “second” … “millisecond” … “now” … “dateDiff” … “lower” … “upper” … “quarter” … “dayOfWeek” … “toDate” … “(” … <STRING_LITERAL> … <DECIMAL_LITERAL> … <INTEGER_LITERAL> … “-” … “true” … “false” … “date” … “timeofday” … “datetime” … “timestamp” … <ID> … <QUOTED_ID> … “min” … “max” … “avg” … “count” … “sum” … “no_values” … “no_format” … “is” … “null” … “year” … “month” … “day” … “hour” … “minute” … “second” … “millisecond” … “with” … “contains” … “starts” … “ends” … “matches” … “like” … “now” … “dateDiff” … “quarter” … “lower” … “upper” … “dayOfWeek” … “toDate” …

対象のクエリ(数式)
ちなみに数式(クエリ)は以下のように、第2引数でセルの値を指定しています。
=query('商品マスタ(完全版)'!$1:$15000, 'ダウンロード'!$L$4)
引用元の値は以下のようになっています。

select A,S,T,U,V,W,X,Y,Z,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR,AS,AT,AU,AV,AW,AX,AY,AZ,BA,BB,BC,BD,BE,BF,BG,BH,BI,BJ,BK,BL,BM,BN,BO,BP,BQ,BR,BS,BT,BU,BV,BW,BX,BY,BZ,CA,CB,CC,CD,CE,CF,CG,CH,CI,CJ,CK,CL,CM,CN,CO,CP,CQ,CR,CS,CT,CU,CV,CW,CX,CY,CZ,DA,DB,DC,DD,DE,DF,DG,DH,DI,DJ,DK,DL,DM,DN,DO,DP,DQ,DR,DS,DT,DU,DV,DW,DX,DY,DZ,EA,EB,EC,ED,EE,EF,EG,EH,EI,EJ,EK,EL,EM,EN,EO,EP,EQ,ER,ES,ET,EU,EV,EW,EX,EY,EZ,FA,FB,FC,FD,FE,FF,FG
これは直接入力したわけでなく数式で自動算出しています。
="select "&textjoin(",",true,$I$22:$I$479)
文字列のselectを先頭において、textjoin関数を使って、「A,B,C,,,,,」といった抽出したい列のアルファベットを指定した文字列を作成しています。
クエリの条件式が短い場合はエラーにならない
ここでポイントですが、上記のようにselect以降とても長い数式になるとこのエラーが発生します。
ですが、短い場合はエラーになりません。
select A,B,C,D,E,F,H,I,J,K,L,M,N,O,P,Q,R

↑
正常に表示される。
エラーの原因
エラーの原因はエラーメッセージに書いてある通りです。
関数 QUERY のパラメータ 2 のクエリ文字列を解析できません。PARSE_ERROR: Encountered ” “by” “BY “” at line ~
この中で重要なのは「PARSE_ERROR: Encountered ” “by” “BY “”」です。
「by」または「BY」はSQLクエリでソートを行う「ORDER BY」で使われる文字列です。このため、Query関数では、BY列ではなく、クエリ指示の一部とみなされエラーになります。
つまり、「by」や「BY」は直接指定できないということです。
対処法
このエラーに対する対処法は大きく2つあります。
- バッククオートで「BY」をくくる
- 「Col列番号」を使う
バッククオートで「BY」をくくる
一つ目はクエリの指示として認識されている「BY」をバッククオートで囲むことです。
これで、文字列であることを明示することができます。
`BY`
なお、バッククオートは「shift + @」で打てます。
クエリの条件式を関数で引っ張ってきている場合は「substitute」を使うと便利です。
="select "&textjoin(",",true,$I$22:$I$479)
↓ 修正
=substitute("select "&textjoin(",",true,$I$22:$I$479),"BY","`BY`")
「Col列番号」を使う
クエリの条件式の中で対象となる列を「Col1, Col2」のような「Col列番号」で指定することもできます。
この場合、query関数の第1引数で指定したデータ範囲に対して、何列目かという指示になります。
QUERY(データ範囲, クエリ, [見出し])
実例
例えば、クエリの部分を以下のように記述することができます。
"select Col1,Col3,Col5"
↓↑ 同じ(データ範囲の開始がA列の場合)
"select A,C,E"
「Col」の冒頭の「C」は大文字である必要があります。
OK:Col1
NG:col1 (エラーになります)
importrange関数のときはColのみ使用可能
なお、Queryのデータ範囲をimportrange関数など他のスプレッドシートのデータを読みこんだときに、A,Bのような列のアルファベットでの指定が使えなくなります。
なので、importrange関数を使ったときはCol番号で指定することが必須となります。