Googleスプレッドシート QUERY関数 超応用例 6(select句 応用編)
Googleスプレッドシートの最強関数 QUERY関数について書いたnoteの第6回です。
👇これまでのQUERY関数シリーズは マガジンにまとめています。
先週のQUERY関数シリーズ 第5回では、 QUERY関数の slect句の基本、出来ること、出来ないことを学びました。
今回は前回の基本を活用した応用編、お題中心です。QUERY関数をより使えるようになりたい人は、全8問にチャレンジしてみましょう!
select句の列指定(識別子)を数式で生成しよう
前回、select句の列指定は A,B,C… という 列のアルファベットではなく、 Col1,Col2,COl3… という列番号指定がおススメと書きました。
でも、この列番号指定を使うと 文字数が増えて記述が煩雑になります。
たとえば 20列あるデータの 1列目だけ除いて selectで指定したい場合、前回書いた通り select句は一つ一つ指定する必要があるので
Col2,Col3,Col4,Col5,Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13,Col14,Col15,Col16,Col17,Col18,Col19,Col20
と 105文字も消費します。
これを短い数式で生成できないか?まずは、これを1つ目のお題としてみましょう!
Q1. QUERY関数のselect句で 20列のデータの 1列目を除いた 2列目~20列目を指定する記述の文字列を数式で生成したい

それでは Col2~Col19までを指定する 文字列
select Col2,Col3,Col4,Col5,Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13,Col14,Col15,Col16,Col17,Col18,Col19,Col20
を数式で簡単に生成する方法はあるでしょうか?
これを考えてみましょう!
↓↓
回答はここから。
↓↓
A1. QUERY関数のselect句で 20列のデータの 1列目を除いた 2列目~20列目を指定する記述の文字列を生成する数式
回答です。

たぶん 一番短い式が
="select Col"&JOIN(",Col",SEQUENCE(19,1,2))
こちらです。
文字数を比較してみると、かなり圧縮されているのがわかりますね。

👇この式で生成された select句の文字列は実際にQUERY関数で使えます。

式を解説していきましょう。
まず2~20までの連番を用意したいので、連番を生成できるSEQUENCE関数を使います。
=SEQUENCE(19,1,2)
※19行、1列の 2から開始する連番を生成

後で連結して文字列化するので、ここで生成する配列は 縦方向、横方向どちらでも構いません。
この連番配列をCol2,Col3,Col4...という文字列にしたいので、

このように考えます。
区切り文字で連結して配列を文字列化する関数は、メジャーなTEXTJOIN関数を使うことも出来るんですが、
今回は
・対象の配列は 1列(1行)の一元配列である
・空白行を削除する処理を考慮する必要がない
という要件を満たすので、より記述が短くて済む JOIN関数を使っています。

最後に先頭の 2に Colが足りないので、"select Col" という文字列を & で連結すれば完成。

Colが2回登場するのがイマイチですが、ARRAYFORMULAを使わずに処理できるので、これが一番短いと思います。
Colを1回にしたい場合は、ARRAYFORMULAを使って

=ARRAYFORMULA("select "&JOIN(",","Col"&SEQUENCE(19,1,2)))
こんな式で対応可能です。
ちなみにこのお題、SEQUENCEの回の超応用例でも登場したものです。(使いまわしでスイマセン)
SEQUENCE関数超応用例「Query関数の select句 の記述を簡略化したい」
まずはコレが数式でselect句を生成する基本となります。
Q2. セルにカンマ区切りで列番号の数字を入れたら、列をその順番でQUERY関数で出力したい

続いて別ケースのselect句のお題に挑戦してみましょう。 A2:J12には表_1というテーブルのデータがあります。
L1にカンマ区切りで半角数字で テーブルの列番号を入れた時に、L2セルに入れたQUERY関数で指定した列番号だけをその並び順で表示させたい!というお題です。
つまり、上の画像のように 5,2,4,1 と入力したら
公用語,首都,面積 (km²),国名 の並び順で L2セルを起点に出力したいということです。

ただし、L1セルが空白の場合は 全データをそのまま出力するものとします。

操作した時の動きは👇こんな感じ

どうでしょう、簡単でしょうか?
元データとして👇をA2セルに貼り付け、テーブル化して利用ください。
国名 首都 人口 (概算) 面積 (km²) 公用語 通貨 GDP (概算) 主要産業 宗教 時差 (日本時間)
日本 東京 126000000 377975 日本語 円 5兆ドル 自動車、電子機器 神道、仏教 0時間
アメリカ合衆国 ワシントンD.C. 330000000 9833520 英語 ドル 21兆ドル IT、金融 キリスト教 -14時間
中国 北京 1400000000 9596961 中国語 元 14兆ドル 製造業、輸出 無宗教、仏教 -1時間
インド ニューデリー 1380000000 3287263 ヒンディー語 ルピー 3兆ドル IT、農業 ヒンドゥー教 -3.5時間
ブラジル ブラジリア 212000000 8515767 ポルトガル語 レアル 2兆ドル 農業、鉱業 キリスト教 -12時間
ロシア モスクワ 144000000 17098242 ロシア語 ルーブル 1.7兆ドル エネルギー、資源 ロシア正教 -6時間
メキシコ メキシコシティ 128000000 1964375 スペイン語 ペソ 1.2兆ドル 製造業、観光 キリスト教 -15時間
インドネシア ジャカルタ 273000000 1904569 インドネシア語 ルピア 1兆ドル 農業、製造業 イスラム教 -2時間
イギリス ロンドン 67000000 242495 英語 ポンド 3兆ドル 金融、サービス キリスト教 -9時間
フランス パリ 65000000 551695 フランス語 ユーロ 2.7兆ドル 観光、製造業 キリスト教 -8時間考えてみましょう!
ちなみに簡単だ!っていう人は、IF関数による分岐を使わない式も考えてみましょう!
↓↓
回答はここから。
↓↓
A2. セルにカンマ区切りで列番号の数字を入れたら、列をその順番でQUERY関数で出力する
回答です。2つ用意しました。

=QUERY(表_1[#ALL],IF(L1="",,"select Col"&SUBSTITUTE(L1,",",",Col")))
まず1つは正攻法で 空白時を IFで分岐させた上で、SUBSTITUTE関数で置換する方法です。
まず、こちらを解説していきましょう。
第1引数は構造化参照が使えるので 見出しを含めたテーブル全体を
表_1[#ALL] で指定します。
今回は Q1と違って連番を生成する必要がないので SEQUENCEは登場しません。

まず L1に入れた 5,1,2 といった 文字列をどう Col5,Col1,Col2 に成形するか?を考えます。
ここで使えるのが置換関数の SUBSTITUTE関数。
SUBSTITUTE(L1,",",",Col")
数値を区切る ,(カンマ) を ,Col に置換することで、5,Col1,Col2 となります。
これだと先頭のColが足りないので 頭に "Col" を &で連結。

これでカンマ無しの単体数値のみの場合も対応できます。
あとは空白時の処理をIFで分岐させるだけ。
頭に Colを付ける際に selectもセットで "select Col" として &で連結すればスッキリ書けますね。

L1が空白の時はIFで空白を返し、select句を省略とすれば完成です。この正攻法が一番短い式じゃないかと思います。
A2【別解】. セルでカンマ区切りで列番号の数字を入れた列を、その順番でQUERY関数で出力する
もう一つの回答、 IFを使わない式ということで

=QUERY(表[#ALL],
REGEXREPLACE("select " &TEXT(L1,"0;;\*;@"),"(\d+)","Col$1"))
REGEXREPLACE関数とTEXT関数を使った、こちらの式も紹介しておきます。
まず 先ほどと同じように L1セルに入った
5,2,1 のような文字列を Col5,Col2,Col1
としたいので、SUBSTITUTE関数とは別の置換関数、正規表現が使える REGEXREPLACE関数を使ってみます。

=REGEXREPLACE(L1,"(\d+)","Col$1")
第2引数で "(\d+)" と指定することで、L1セル内の連続する数字の塊をキャプチャ(保存)すれば、第3引数で $1として利用できるので、 "Col$1" とすることで、
5,2,1 ⇒ Col5,Col2,Col1
という置換ができます。
SUBSTITUTEの時と違って先頭の Colもこの時点でクリアできます。
ただ REGEX系の関数には弱点があって、

第1引数は文字列のみという制限があり、数値だとエラーになってしまいます。
※Googleスプレッドシートの REGEX系関数の仕様であって、ExcelのREGEX系関数は 数値に対しても使用可能です。
このL1セルが カンマ区切りなしの単体の数字(数値)だった場合のエラーと L1セルが空白だった時の対処をまとめて解決するのが REGEXREPLACE関数の第1引数としている
"select " &TEXT(L1,"0;;\*;@")
この部分です。
TEXT関数の第2引数の "0;;\*;@" ですが、これは セミコロン ; で区切る表示形式の書き方
正の数の時 ; 負の数の時 ; ゼロの時 ; 文字列の時
この分岐を使っています。
TEXT関数で第1引数が空白だった場合は、 0と扱われ ゼロの時の表示形式が適用されます。

今回の第1引数の L2は
正の数の時 ・・・ そのまま数値を表示
負の数の時 ・・・ 考慮不要(空白でOK)
0の時(空白) ・・・ "*" としたい
文字列 ・・・ そのまま文字列を表示
としたいので
"0;;*;@"
としたいところですが、 * は表示形式では特殊な意味合いを持つ文字なのでエスケープさせる記号 \ を付けて "0;;\*;@" としています。
※表示形式のメタ文字のエスケープは Googleスプレッドシートの場合は \ ですが、Excelだと ! を使います
つまりIFを使わずTEXT関数で分岐をさせたってわけです。

他の解法もありますが、代表的な2つの回答を紹介しました。
Q3. 複数選択プルダウンで見出しを選択して、選択した順番でQUERY関数で表の列を出力したい
先ほどのQ2のお題ですが、列番号を入れる方式なんで、どの列が何番目か?を利用者が確認するのが手間ですし、手入力なので 全角数字を入力してしまうケースや「 ,」(カンマ)じゃなくて 「、」が使われ表記のブレが発生するケースも考慮する必要があります。
これらを解決するのが
列の見出しを手入力ではなく選択できる
選択した順番に並べることができる
を可能とする Googleスプレッドシートの 複数選択プルダウンです。
👇 表の見出し =表_1[#HEADERS] を プルダウン範囲として指定して、「複数選択できるようにする」にチェックを入れ、L1セル を複数選択プルダウンで 表の見出しが選べる状態として

選択した順番で 表の列が出力されるようにするには、L2セルにQUERY関数を使ったどんな式を入れればよいか? というお題です。(今回はQUERY関数を使うことが前提です)
Q2のお題と同じく L1セルが空白(プルダウンで何も選択していない)の時は、全ての列を出力するものとします。

Q1、Q2を組み合わせて応用する問題です。考えてみましょう!
考えてみましょう!
↓↓
回答はここから。
↓↓
A3. 複数選択プルダウンで見出しを選択して、選択した順番でQUERY関数で表の列を出力する
回答です。
=ARRAYFORMULA(QUERY(表_1[#ALL],IF(L1="",,"select Col"&
JOIN(",Col",XMATCH(SPLIT(L1,", ",FALSE),表_1[#HEADERS])))))

まず前提として、複数選択プルダウンの中身は ", "(カンマ 半角スペース)で 選択肢が区切られた文字列データとなっています。
だから式の処理としては
SPLIT関数で ", "(カンマ 半角スペース)で分割
▼
XMATCH関数(またはMATCH関数)で 各文字列が
表の見出しの左から何番目に存在するかを判定
(これが、そのまま列番号になる)
▼
問1のお題と同じく JOIN関数による連結
▼
問2のお題と同じく IFで空白時を分岐
こんな流れになります。
ポイントとしては、Geminiで生成した今回の表データに

このように半角スペースを含む見出しがあるので、
SPLIT(L1,", ") としてしまうと、この半角スペースでも分割されてしまいます。
これを回避する為に SPLIT(L1,", ",FALSE) と 第3引数をFALSE指定することで、", " (カンマスペース)の塊で区切るようにしてる点。
SPLIT関数の基本 (第3引数FALSEで 文字列で区切る)
また、その後の XMATCH関数の処理は 第1引数に配列をとることになるので、ARRAYFORMULAで括る必要がある点にも注意です。

列番号の配列までもっていければ、あとはお題1、お題2の処理が使えますね。
複数の関数を組み合わせるのが難しく感じるかもしれませんが、この処理が使えると非常に便利なので、しっかり理解しておきましょう!
Q4. 出力しない列番号をカンマ区切りで指定して、それ以外の列だけをQUEERY関数で出力したい

数式で select句の列指定を生成するお題の最後です。
同じ表を利用して L1 セルに 今回は 「出力しない」列番号をカンマ区切りで入れた時に、それらの列を除外した結果を出力するには、L2セルにどんなQUERY関数の数式を入れればよいでしょうか?

今回も空欄の場合は、表をそのまま出力するものとします。
簡単って人は、IFを使わない式で出来るか考えてみましょう!
↓↓
回答はここから。
↓↓
A4. 出力しない列番号をカンマ区切りで指定して、それ以外の列だけをQUEERY関数で出力する
回答です。
=QUERY(表_1[#ALL],"select Col"&JOIN(",Col",
UNIQUE(TOCOL({SPLIT(L1,","),SEQUENCE(1,COLUMNS(表_1))},3),,TRUE)))

指定した列を出力しない ということで、指定した列を除く処理を FILTER関数で対処することも可能ですが、今回はUNIQUE関数を使ってみました。
順にみていきましょう。
L2セルでカンマ区切りで指定した列番号は、このままだと文字列なので、扱いやすいように 先にSPLIT関数でカンマ区切りで分割して配列化します。

また出力させる列番号を生成する為に、SEQUENCE関数を使って全列番号の配列も用意しておきます。

COLUMNS(表_1) で表の列数 10を取得し、SEQUENCE関数で1から連番を生成することで、全列番号の配列を用意します。
この時、SPLIT関数で分割した配列は 横に展開されるので、これに合わせる形でSEQUENCE関数も 縦方向に展開される SEQUENCE(COLUMNS(表_1))ではなく、横方向に展開される SEQUENCE(1,COLUMNS(表_1)) としておきます。
この2つを比較して
SEQUENCE(1,COLUMNS(表_1))
の中から
SPLIT(L1,",")
に存在しない ものを取得したいので、

このようにFILTER関数を使ってもいいんですが、ちょっと煩雑ですよね。
ここで 2つの配列を { , } で 横連結した上で、UNIQUE関数の第3引数TRUEを使って

=UNIQUE({SPLIT(L1,","),SEQUENCE(1,COLUMNS(表_1))},TRUE,TRUE)
こんな式で、重複していない値だけを出力できます。
第3引数 TRUE指定で 一つしか登場しないデータを取得できる
ただし、L2が空白だった時にこの式は

SPLIT関数の結果 #VALUE!エラーと 1,2,3… という配列を横に連結した結果を返します。
このエラーを TOCOL関数の 第2引数 2(または3)指定で除外します。
=UNIQUE(TOCOL({SPLIT(L1,","),SEQUENCE(1,COLUMNS(表_1))},3),,TRUE)
ここで TOROW関数ではなく、あえてTOCOL関数を使って結果を縦方向の一次元配列にしているのは、縦にしておけば UNIQUE関数の第2引数で指定している TRUE (横方向に重複をチェック)を省略できるからです。

これでIFで分岐せずに 空白時に全列を出力することが出来ますね。
あとは、Q1のJOIN連結を使って select句の列指定文字列を生成すればOK。

UNIQUE関数はこんなところでも使えるんですね!
【余談】選択した列番号を前(左)に出力して、残りをそのままの順番で出力する
ちなみに、Q4とほぼ同じ回答になるんでお題にはしませんが、先ほどの式のUNIQUE関数の第3引数を省略することで、L2セルでカンマ区切りで指定した列番号を指定順に先に表示(より左側に表示)させ、残りの列はその後ろ(右)にそのままの順番で表示させることも出来ます。

=QUERY(表_1[#ALL],"select Col"&
JOIN(",Col",UNIQUE(TOCOL({SPLIT(L1,","),SEQUENCE(1,COLUMNS(表_1))},3))))
また、今回紹介したテクニックは いずれも Col を付けて成形、文字列化の部分以外は、CHOOSECOLS関数にも使えるものです。

数式でselect句の列指定文字列を生成するお題を幾つか紹介しました。
select句の合わせ技の超応用例
前回のnoteで紹介しましたが、QUERY関数のselect句は単純に列を指定するだけではなく、集計関数やスカラー関数、演算子、値の直接指定などの合わせ技が可能です。
続いて、このselect句の合わせ技を使った応用例のお題を見ていきましょう。
※一部、現在は他の関数を使った方が良いケースもあります
Q5. QUERY関数で行毎の平均値を一つの式で算出したい!

画像のように 生徒毎に第1回から5回までのテスト結果をまとめた マトリックス表があります。
これを生徒毎の(行毎の) 平均点を H1に一つの式をいれて一気に算出したい。というお題です。
なお、テストは欠席した場合は 点数を入れるセルに「欠席」の文字が入っており、欠席を除外した平均点を算出するものとし、テストの回数が増えた時には参照範囲の変更のみで対応できる式にするとします。
また「平均点」という見出しも QUERY関数で生成するものとします。
わざわざQUERY関数を使わなくてもいいんですが、LAMBDA登場前でも 実はQUERY関数で 行毎の 合計や 平均、最大値が一発で算出できたのよーってことを知ってもらうお題です。
データはコチラをお使いください。
第1回 第2回 第3回 第4回 第5回
田中 100 90 95 95 100
佐藤 80 欠席 70 70 75
鈴木 90 100 95 100 欠席
橋本 95 80 75 90 90考えてみましょう!
↓↓
回答はここから。
↓↓
A5. QUERY関数で行毎の平均値を一つの式で算出する
回答です。

=QUERY(TRANSPOSE(QUERY(TRANSPOSE(B2:F5),"select '平均点',avg(Col"&JOIN("),avg(Col",SEQUENCE(ROWS(B2:F5)))&")")),"select Col2")
QUERY関数2回使ってるのズルいじゃない!と思うかもw これは、さすがに1回では厳しいです。
解説していきましょう。
まず、平均を出したいので 通常は AVERAGE関数の出番ですが、今回はQUERY関数のお題なんで 集計関数の avg を使いたいと考えます。
集計関数は列毎(縦方向)にしか使えないので、まずTRANSPOSE関数で縦横変換をしましょう。

使うのはデータ部分だけでよいので TRANSPOSE(B2:F5) とします。
これで 4列のデータとなったんで、
select avg(Col1),avg(Col2),avg(Col3),avg(Col4)
とすれば良いんですが、お題の条件に
「回数が増えた時には参照範囲の変更のみで対応できる式にする」
があるので、ここを数式で生成しましょう。
Q1のJOIN連結の応用です。

="select avg(Col"&JOIN("),avg(Col",SEQUENCE(ROWS(B2:F5)))&")"
集計関数部分の文字列を生成する為に JOIN関数では "),avg(Col" という区切り文字で連結させ、前に "select avg(Col"& 、後ろに &")" を連結させます。
TRANSPOSE後の列数は元データの行数なんで 列番号配列は
SEQUENCE(ROWS(B2:F5))
で生成すれば良いですね。

QUERY関数の第2引数に入れれば、👆このように 横方向で見出し付きですが、各列(元データの行)の平均が算出できました。
この余分な avgの見出しを削除するのに label句を使う方法もありますが、ちょっと数が多いと面倒です。
またINDEX関数を使って2行目だけ取得する方法もいいんですが、せっかくのQUERY関数 select句の回なんで、今回はこれをフル活用しましょう。
で、この時点で「平均点」の見出しも select句 の値指定を使って生成しちゃいましょう。

=QUERY(B2:F5,"select '平均点',avg(Col"&JOIN("),avg(Col",SEQUENCE(ROWS(B2:F5)))&")")
あとは、これを再度TRANSPOSEで縦に戻して

2回目のQUERY関数で 2列目だけとすれば 完成です。
=QUERY(TRANSPOSE(QUERY(TRANSPOSE(B2:F5),"select '平均点',avg(Col"&JOIN("),avg(Col",SEQUENCE(ROWS(B2:F5)))&")")),"select Col2")
まぁ、今だったら BYROW関数を使った方が圧倒的に簡単なんで、そっちを使いましょうw

=BYROW(B2:F5,LAMBDA(r,AVERAGE(r)))
ちなみにお題は行ごとだったんで、TRANSPOSEを使ったりと少し工夫が必要でしたが、列ごとの集計ならもっと簡単にQUERY関数で処理できます。

=INDEX(QUERY(B2:F5,"select "&"max(Col"&JOIN("),max(Col",SEQUENCE(COLUMNS(B2:F5)))&")"),2)
QUERY関数の 行毎、列毎の集計は 過去に便利だったテクニックですが、せっかくの機会なんで紹介させていただきました。
Q6. QUERY関数で同じ列(数値型)を複数回 指定したい

前回のnoteで QUERY関数の select句は 同じ列を何度も指定が出来ないと書きました。
まぁ事前にCHOOSECOLS関数を使うか、第1引数の段階で中カッコの配列連結で加工すればいいんですが、一応 QUERY関数でも同じ列を複数回指定する方法があるよってお題です。
画像のような 列1~列3の 3列データ(全て数値型)が A1:C11にあったとして、これをQUERY関数で 各列を3回ずつ出力させたい時、どのようにselect句を記述すればよいでしょうか?
列1 列2 列3
1 11 21
2 12 22
3 13 23
4 14 24
5 15 25
6 16 26
7 17 27
8 18 28
9 19 29
10 20 30あまり実務で役に立つお題ではないですが、考えてみましょう!
なお、見出しが生成されてもそのままで良いとします。
↓↓
回答はここから。
↓↓
A6. QUERY関数で同じ列(数値型)を複数回 指定する
回答です。

=QUERY(A1:C11,"select Col1,Col1*1,Col1*1*1,Col2,Col2*1,Col2*1*1,Col3,Col3*1,Col3*1*1")
ちょっと煩雑ですが、こんな式になります。
一応 クエリ文を数式で生成できますが、3列3回繰り返し程度だと記述の長さは、むしろ長くなります。
=QUERY(A1:C11,"select "& ARRAYFORMULA(TEXTJOIN(",",,"Col"&SEQUENCE(3)&REPT("*1",SEQUENCE(1,3)))))
少し解説しましょう。
QUERY関数は 同じ列を1回しか指定できないんですが、

=QUERY(A1:C11,"select Col1,Col1*1")
このように 演算子で加工した場合は、元の列指定とは別モノとして利用できます。
よって数値型であれば 値が変化しない +0 や *1 とした場合、実質的にselect句で同じ列を2回選択することが出来ると言えます。
ただ、同じ列に対して同じ加工は2回使えません。

その為、同じ列を3回、4回 利用したい場合は、
1回目 Col1
2回目 Col1*1
3回目 Col1*1*1
4回目 Col1*1*1*1
といった感じで +0や*1を繰り替えして変化させる必要があります。
ここでREPT関数の第2引数にSEQUENCEを使うテクニック、そして縦横の一次元配列を &で連結させ 縦*横の配列を生成するスピル処理が使えます。

あとはTEXTJOIN関数でカンマ連結すればOKですね。
ただQUERY関数の select句で合わせ技を使うと

どうしても見出しが生成されてしまうので、これの処理が面倒なのもあって、実用的とは言えません。
ぶっちゃけ CHOOSECOLS関数を使った方がいいです。
Q7. QUERY関数で同じ列(文字列型)を複数回 指定したい
一応、同じようにQUERY関数の select句で複数回指定する対象が 文字列型の場合はどうすればよいか? もお題としておきましょう。

実は「文字列型」とした場合は、よい解法がないので今回は対象の文字列データは、日本語(ひらがな、カタカナ、漢字の組み合わせ)の画像のA列のようなデータに限定します。
列1
山田たろう
田中ジャスティス
鈴木ビーバー
佐藤こういち
橋本ローラ先ほどと同様に 生成される見出しは気にしなくてOKです。この A1:A6をQUERY関数の第1引数として select句で 3回出力 するにはどうすればよいか?
考えてみましょう!
↓↓
回答はここから。
↓↓
A7. QUERY関数で同じ列(文字列型)を複数回 指定する
回答です。

=QUERY(A1:A6,"select Col1,upper(Col1),upper(upper(Col1))",1)
ちなみにお題は 3回なんで シンプルに 👇でもOK。
=QUERY(A1:A6,"select Col1,upper(Col1),lower(Col1)",1)
考え方は 先ほどの数値型の列の複数回指定と同様で、テキスト型の列も何かしら加工をすれば同じ列の指定が可能となることを利用します。
ただし文字列に対しては演算子は一切使えないので、アルファベットを含まない文字列には一切影響を与えないスカラー関数の upper() か lower() を活用します。
複数回登場させる場合は、重ねがけ upper(upper(Col1)) をすることで、加工の重複も回避できます。

=QUERY(A1:A6,ARRAYFORMULA(CONCATENATE(IFNA(HSTACK("select ",REPT({"upper(","Col1",")"},SEQUENCE(5)^{1,0,1})),","))),1)
👆このように繰り返し回数を指定して数式で生成することも出来るんですが、面倒ですし実用性があまりないので説明は割愛します。
Q8. QUERY関数で表を各列の間に空白列を挟んだ形にして出力したい
最後のお題です。

このように お題2で使ったテーブル 表_1 に対して、QUERY関数で各列の間に空白列を挟んだ形にして出力したい場合、どのような式を組めばよいでしょうか?
今回も 見出しが生成されても気にしないものとします。また10列目の右側にも空白列が生成されて良いとします。
考えてみましょう!
↓↓
回答はここから。
↓↓
A8. QUERY関数で表を各列の間に空白列を挟んだ形にして出力する
回答です。

=QUERY(表_1[#ALL],"select "&ARRAYFORMULA(
TEXTJOIN(",",,TEXT(SEQUENCE(COLUMNS(表_1)),{"Col0","0/\0"}))))
TEXT関数を使わず 👇 のように &で連結でもOKです。
=QUERY(表_1[#ALL],"select "&ARRAYFORMULA(
TEXTJOIN(",",,{"Col",""}&SEQUENCE(COLUMNS(表_1))&{"","/0"})))
解説していきましょう。
まずQUERY関数において空白列を生成する方法は、1/0 のように #DIV/0!エラーとなる演算をselect句で指定します。

これは前回やりましたね。
つまり 表の列数(今回のお題では10列)に対して間に 重複しないように
1/0,2/0,3/0 を挟んだ
Col1,1/0,Col2,2/0,Col3,3/0,Col4,4/0,Col5,5/0,Col6,6/0,Col7,7/0,Col8,8/0,Col9,9/0,Col10,10/0
こんな文字列を生成すれば良いわけです。本当は最後の 10/0は不要なんですが、これを省こうとすると面倒なのでこのままでOKという条件にしました。
これを数式で生成するのに、まずSEQUENCE(COLUMNS(表_1)) で10までの連番を生成、
ここから Col1,Col2 と頭に Colを付けた配列と 後ろに /0を付けた配列を生成する為に TEXT関数の第2引数を 配列にします。
ただ、数値の後ろに /0を付ける書式を "0/0" としてしまうと

このようになってしまうので、エスケープ \ を使います。 0だけでなく / もエスケープが必要なので

TEXT関数の第2引数は、 {"Col0","0\/\0"} このようになります。
ここで配列処理が必要となるのでARRAYORMULAを付けて
ARRAYFORMULA(TEXT(SEQUENCE(COLUMNS(表_1)),{"Col0","0\/\0"}))
あとは カンマで連結すればOKですが、2列10行の配列なので JOIN関数が使えません。ここは 二次元配列に使える TEXTJOIN関数を使って連結します。

QUERY関数の第2引数で "select "と&でつなげば完成です。
=QUERY(表_1[#ALL],"select "&ARRAYFORMULA(
TEXTJOIN(",",,TEXT(SEQUENCE(COLUMNS(表_1)),{"Col0","0/\0"}))))
ただ謎の見出しが生成されちゃうし、これを処理するのが面倒なんで

これも今だったらCHOOSECOLS関数を使うケースですね。

=CHOOSECOLS(IFNA(HSTACK(表_1[#ALL],"")),{SEQUENCE(10),SEQUENCE(10,1,11,0)})
QUERY関数 select句を使いこなす
今回は QUERY関数の select句を使いこなすためのテクニックをお題形式で紹介しました。
合わせ技の方は、LAMBDAヘルパー関数やCHOOSECOLSなどの新関数が登場した今となっては実用性は低いですが、工夫次第でQUERY関数が様々な使い方が出来ることが伝わったんじゃないでしょうか。
お題を通じて UNIQUE関数やTEXT関数、JOIN関数を使った、配列・文字列の操作テクニックに発見があった人もいたかと
select句の応用例の最も曲芸的なネタは QUERY関数シリーズの第4回で紹介しています。
👆まだ読んでない人は、是非こちらも確認してみてください。
QUERY関数シリーズ、次はいよいよ クエリ文のメインと言える where句に入っていきます。
where句もかなり奥が深く長くなりそうなんで、別ネタで小休止を入れてから突入したいと思います。
次回はGoogleスプレッドシートの隠し関数ネタを予定。
いいなと思ったら応援しよう!
チップ大歓迎です。やる気がアップしますw