かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Google Spreadsheet query でヘッダーを出力しない方法

複雑な条件を query で取得して集計した結果だけを表示したい

Spreadsheet の query はデフォルトで header が出力される

Spreadsheet QUERY sample

上記のようなデータがあり price >= 2000 のレコード数をだそうを query で下記のような関数を書くと count というヘッダーが表示されてしまう

= QUERY(A2:C10, "SELECT count(A) WHERE ${条件}", FALSE)

QUERY(データ, クエリ, [見出し])
見出し - [省略可] - データの上部にある見出し行の数です。省略した場合や -1 と指定した場合は、データの内容に基づいて推測されます。
cf. QUERY - Google ドキュメント エディタ ヘルプ

⚠️ query の第三引数を false にしたら見出しが出力されないわけではない

明示的に LABEL を空文字にすればヘッダーが表示されなくなる

明示的に LABEL ${countカラム名} '' を quey の SQL に追加すればヘッダーが表示されなくなる

= QUERY(A2:C10, "SELECT count(A) WHERE ${条件} LABEL count(A) ''", FALSE)

Spreadsheet QUERY Sample

🐞 count 数が 0 のときエラーになる

ヘッダーを非表示にしたとき、count した結果が 0 件のとき下記のようなエラーが表示される

Spreadsheet QUERY sample #N/A クエリが空の出力で完了しました。

明示的に IFERROR で囲って 0 件の表示をすればOK

= IFERROR(QUERY(A2:C10, "SELECT count(A) WHERE ${条件} LABEL count(A) ''", FALSE), 0)

Spreadsheet QUERY sample

Spreadsheet の QUERY で使える SQL っぽいのクセが強かった


[参考]

Google Spreadsheet COUNTIFS で OR 条件を使いたい

Google Spreadsheet で条件に当てはまるレコード数をカウントしたい時に COUNTIF や COUNTIFS を使うが、複数条件ある時 COUNTIFS だとデフォルトが AND になるので OR でカウントしたいときの Tips

サンプルデータ

A B C
1 販売商品コード 商品名 単価
2 A1012 ChatGTP入門 1670
3 A1018 React 入門コース 5800
4 A1020 プログラミング入門コース 2800
5 A1012 ChatGTP入門 1670
6 A1016 STUDIO デザインコース 2400
7 A1011 Spotifyコース 5800
8 A1018 React 入門コース 5800
9 A1019 AI 入門コース 2400
10 A1019 AI 入門コース 2400
11 A1012 ChatGTP入門 1670
12 A1020 プログラミング入門コース 2800

商品名が ChatGTP入門 or AI 入門コース のレコード数を求める

1. 別々に COUNTIF で数を求め合算する

重複が発生しない条件なら、シンプルに条件ごとに COUNTIF で集計したものを足せば良い

= COUNTIF($B$2:$B$12, "ChatGTP入門") + COUNTIF($B$2:$B$12, "AI 入門コース")
// => 5

COUNTIF を足していく方法はシンプルで可読性も高いが、条件が増えると記述が面倒…

2. OR 条件を 配列 {} で定義する方法

🙅 動作しない
= SUM(COUNTIFS($B$2:$B$12, {"ChatGTP入門", "AI 入門コース"}))
// => 3

Excel では上記のように COUNTIFS の条件を 配列 {} 内に複数書けば OR 条件として動作するような記述があるが Google Spreadsheet では、最初の条件のレコードのみが返され、意図したとおりに動作しない

🙆 Google Spreadsheet では ARRAYFORMULA で囲えば OK
= ARRAYFORMULA(SUM(COUNTIF($B$2:$B12, {F2, F3})))
// => 5

3. MAP + LAMBDA を使う方法

MAP関数 MAP(配列1, [配列2, ...], LAMBDA)
この関数は、LAMBDA 関数を各値に適用して、指定した配列内の各値を新しい値にマッピングします。
cf. MAP function - Google Docs Editors Help
LAMBDA 関数 LAMBDA(名前, 数式)
一連の名前とそれらを使用する数式を含むカスタム関数を作成して返すことができます。 cf. LAMBDA function - Google Docs Editors Help

=COUNTIF(MAP($B$2:$B12, $B$2:$B12, 
  LAMBDA(a, b, OR(a="ChatGTP入門", b="AI 入門コース")))
  , TRUE)
// => 5

条件の分だけ範囲を作って渡す必要があるので、条件が多くなると少し見通しが悪くなりそうだと感じた


複数の OR 条件を AND したい場合

(A OR B OR C) AND (D OR E) のようなケース

商品名が React 入門コース or Spotifyコース or プログラミング入門コース or STUDIO デザインコース かつ 単価が 5000 以上 or 2500以下 のレコード数を求める
(該当レコードは: 3 React 入門コース 5800, 6 STUDIO デザインコース, 2400, 7 Spotifyコース 5800,8 React 入門コース 5800 なので 4 になればよい

🙅 CONTIF を足すを方法では定義できない

全てが OR 条件になってしまうので AND 条件を表現できない

=(COUNTIF($B$2:B$12, "React 入門コース") + COUNTIF($B$2:B$12, "Spotifyコース") + COUNTIF($B$2:B$12, "プログラミング入門コース") + COUNTIF($B$2:B$12, "STUDIO デザインコース"))
 + (COUNTIF($C$2:C$12, ">=5000") + COUNTIF($C$2:C$12, "<=2500")) 
// => 15

🙅 配列 {} 定義・MAP + LAMBDA はエラーになる

配列 {} 定義
=ARRAYFORMULA(
  SUM(
    COUNTIFS(
      $B$2:$B$12, {"React 入門コース", "Spotifyコース", "プログラミング入門コース", "STUDIO デザインコース"},
      $C$2:$C$12, {">=5000", "<=2500"}
    )
  )
)
// => #VALUE 

-> COUNTIFS の配列引数のサイズが異なります。

MAP + LAMBDA
=COUNTIFS(
  MAP($B$2:$B$12, $B$2:$B$12, $B$2:$B$12, $B$2:$B$12,
    LAMBDA(a, b, c, d OR(a="React 入門コース", b="Spotifyコース" c="プログラミング入門コース", d="STUDIO デザインコース"))), TRUE,
  MAP($C$2:$C$12, $C$2:$C$12,
    LAMBDA(a, b OR(a>=5000, b<=2500))), TRUE
)
// => #ERROR!

-> 数式の解析エラーです。

🙆 素直に query を使う

query を使い結果を count で出せば良い

=QUERY(A2:C12, 
  "SELECT count(A) 
   WHERE
     (B = 'React 入門コース' OR B = 'Spotifyコース' OR B = 'プログラミング入門コース' OR B = 'STUDIO デザインコース') 
     AND (C >= 5000 OR C <= 2500)
   LABEL count(A) ''"
)
// => 4

素直に query で書くほうが SQL が読めるなら見通しも良くて良い

まとめ

  1. OR 条件が1つだけなら ARRAYFORMULA(SUM(COUNTIF(範囲, {条件1, 条件2, 条件3, ...}))) か Query を使うのが良さそう
  2. 複数の OR 条件を AND するような複雑な条件の場合は、素直に query を使い結果を count(A) のような形で出すのが良い

[参考]

Google Spreadsheet 月末・月初の日付を求める・query に日付を使う

n月中のデータを query で一覧にしたい時などに割と使うアレ

月末・月初の日付を求める

EOMONTH を使う

EOMONTH(開始日, 月数)
起算日から指定した月数だけ前または後ろの月の最終日の日付を返します。

  • 開始日 - 結果を計算するための起点となる日付です。
  • 月数 - 開始日の前(負)または後ろ(正)の計算対象となる月数です。計算結果の月の最後の暦日が返されます。

使用例
EOMONTH(DATE(1969, 7, 20), 1) / EOMONTH(A2, 1) / EOMONTH(40909, -2)

cf. EOMONTH - Google ドキュメント エディタ ヘルプ

月末の日付

当月末なので下記で求められる

= EOMONTH(開始日, 0) // 開始日の月末の日付

月初の日付

先月末日 + 1日で求められる

= EOMONTH(開始日, -1) + 1 // 開始日の前月末 +1日 = 開始日の月初の日付

query の条件に日付を使う

Google Spreadsheet の query の条件に日付を使うには date 'YYYY-MM-DD' の形式にする必要がある
参考: Query Language Reference (Version 0.7)  |  Charts  |  Google for Developers

例えば A1 にある日付 2025/10/15 を条件にするなら下記のように TEXT を使い YYYY-MM-DD 形式に変換する必要がある

SELECT * WHERE Col1 < date '"& TEXT(A1, "YYYY-MM-DD") &"'

該当月 (月初〜月末) であることを条件にする

A1 セルに対象月となる日付が入っている場合下記のようになる

= query(
  'シート!'A:Z,
  "SELECT *
   WHERE A >= date '"& TEXT(EOMONTH(A1, -1) + 1, "YYYY-MM-DD") &"'
   AND A <= date '"& TEXT(EOMONTH(A1, 0), "YYYY-MM-DD") &"'"
)

まとめ

  • 月初日を返す関数はないので
    • 月初は EOMONTH(M, -1) で先月末を求め +1 する
  • query の条件に日付を使うには
    1. YYYY-MM-DD の文字列に変換する必要があること
    2. date 'YYYY-MM-DD' の形式である必要があること

おわり


[参考]