見出し画像

Googleスプレッドシート QUERY関数 超応用例 13(日付、日時、時刻を極める)

Googleスプレッドシートの最強集計関数 QUERY関数について書いたnoteの第13回です。

👇これまでのQUERY関数シリーズは マガジンにまとめています。QUERY関数をハイレベル(廃レベル)に使いこなしたい人は必読です!

前回はQUERY関数の 日付・日時・時刻を加工できる スカラー関数 について書きました。

今回は 

  1. 日付・日時・時刻のリテラル 記述ルールを理解する

  2. 日付・日時・時刻で比較演算子が使えることを理解する

  3. 日付・日時・時刻を加工できるスカラー関数を理解する 👈今回応

  4. 日付・日時・時刻で文字列比較演算子を使う方法を理解する 👈今回理解

スカラー関数の応用と文字列比較演算子を取り上げていきます。




3(続き). 日付・日時・時刻を加工できるスカラー関数を理解する

前回 基本を紹介した 日付・日時・時刻を加工する為の 12のスカラー関数

$$
\begin{array}{lll}
\text{No}&\text{スカラー関数}&\text{解説}\\ \hline
\text{1}&\text{year()}&\text{日付または日時の値から年を数値で返す}\\ \hline
\text{2}&\text{month()}&\text{日付または日時の値から月を数値で返す
※月の値は0スタート}\\ \hline
\text{3}&\text{day()}&\text{日付または日時の値から日を数値で返す}\\ \hline
\text{4}&\text{hour()}&\text{日時または 時刻から時間の値を数値で返す}\\ \hline
\text{5}&\text{minute()}&\text{日時または 時刻から分の値を数値で返す}\\ \hline
\text{6}&\text{second()}&\text{日時または 時刻から秒の値を数値で返す}\\ \hline
\text{7}&\text{millisecond()}&\text{日時または 時刻からミリ秒の値を数値で返す}\\ \hline
\text{8}&\text{quarter()}&\text{日付または日時の値から四半期を数値で返す}\\ \hline
\text{9}&\text{dayOfWeek()}&\text{日付または日時の値から曜日を数値で返す
※日曜日から1始まり}\\ \hline
\text{10}&\text{now()}&\text{現在の日時をかえす
※GMT タイムゾーン}\\ \hline
\text{11}&\text{dateDiff()}&\text{2 つの 日付、または日時の間の日数を数値で返す。}\\ \hline
\text{12}&\text{toDate()}&\text{指定された値を date 値(日付型)に変換する。
※日時や数値(エポック値)を日付に出来る}\\ \hline
\end{array}
$$

https://developers.google.com/chart/interactive/docs/querylanguage?hl=ja#scalar_functions

まずは 前回書ききれなかった スカラー関数を利用の際の注意点、そしてエポックミリ秒変換を使った超応用例をみていきましょう。



where句の中で month(Col1) +1 を 1+month(Col1) と書くとエラーになる

前回登場した、日付や日時データから月を数値として取り出す スカラー関数 month() ですが、これは 1月を 0として扱うという注意点があり、実際の月の数値として扱う為には

month(Col1) + 1

このように +1 する必要があると書きました。

そして当然ですが、select句で これを 1 + month(Col1) としても

同じ結果が返ります。

しかし実は where句 だとこれが成り立ちません。

=QUERY(A2:B9,"where month(Col1) + 1 = 7")

は、1列目(日付型)の月が 7(7月)のデータだけを抽出する式として機能しますが、

=QUERY(A2:B9,"where 1 + month(Col1) = 7") 

並びを変えた 👆こちらだと #VALUE! エラー となってしまいます。

エラーメッセージの後半は

"like" ... "like" ... "like" ... "like" ... "like" ... "like" ... "like" ... "like" ... "like" ... "like" ... "like" ... "like" ... "like" ... "like" ... "like" ... "like" ...

って・・・、ヤンデレ彼女からのメッセージのような恐ろしさw

ちなみに month(Col1) + 1 = 7 を month(Col1) = 7 - 1 としても

本来成り立つはずの式ですが同様にエラーとなります。

この原因は、本来 比較演算子を利用する where句の中で、算術演算子が登場することは想定外である為と思われます。

month(Col1) + 1 が成り立つのは、数値型の列や列をスカラー関数で加工した数値の後ろに来る 算術演算子は 例外的に許可されている(算術演算子として機能する)ルールなんでしょう。

エラーとなってしまう

=QUERY(A2:B9,"where 1 + month(Col1) = 7")

=QUERY(A2:B9,"where month(Col1) = 7 - 1")

という書き方がどうしても必要になる場合は、

計算処理をしたい部分をカッコで括ることで

=QUERY(A2:B9,"where (1 + month(Col1)) = 7")

=QUERY(A2:B9,"where month(Col1) = (7 - 1)")

エラーを回避することが出来ます。

month() +1 をアレンジする際に注意すべき、

where句で算術演算子を使う時にエラーが出る場合はカッコで括る!

というルールの紹介でした。



QUERY関数内で日付をエポックミリ秒変換して計算に利用する【道筋】

続いて QUERY関数で日付を扱った超応用例を紹介しましょう。

前回の最後にスカラー関数の toDate() に関して

日付や日時をエポックミリ秒(数値)に変換できれば、シリアル値と同じように 算術演算子で加算、減算できるようになります。

そして、その結果のエポックミリ秒の数値を 再び toDate()で 日付に戻すことが出来るってことです。

これが出来れば、QUERY関数で 指定した列の日付の〇日後の日付を出力したり、スカラー関数の now()を時差を考慮した 日本時間の日付に変換することも可能となります!

このように書きました。

では、

日付や日時をエポックミリ秒(数値)に変換

これを どう実現すればよいか?

いきなりお題に挑戦だと難しすぎるんで、少し理解の道筋(ヒント)を記載します。

そこからお題に挑戦してみましょう。


まず、エポックミリ秒は 1970/01/01 00:00:00.0000として、そこから 1ミリ秒を1としてカウントした数値です。

だから 1970/01/01 00:00:00.001 は 1です。

1日後の 1970/01/02 00:00:00.000 は、1日(24時間)をミリ秒換算した

24 * 60 * 60 * 1000 = 86400000
時 分 秒 ミリ秒 

がエポックミリ秒となります。これが1日分のミリ秒です。

ということは、1970/01/30 00:00:00.000 は、

29 * 24 * 60 * 60 * 1000
 時 分 秒 ミリ秒 

このように1970/01/01 からの日数(30-1)に 24*60*60*1000 をかければよいとなります。

👆 スカラー関数のtoDate関数で日付に戻すと 1970/01/30 になってますね。


でも、シート関数なら除算でいけるけど日付型に+ や - など算術演算子が使えないQUERY関数内で  日数をどうやって求めたら・・・

思い出してください!

スカラー関数には 2つの日付の差分の日数を算出する dateDiff() がありましたよね。

そう 日付 ▶ エポックミリ秒 変換の決め手は スカラー関数 dateDiff()の活用なんです!

では超応用例のお題にチャレンジしてみましょう。



Q1. QUERY関数で 開始日と予定日数から終了予定日を計算して出力したい

画像左のような イベント計画表というテーブルがあり、タスク名、担当者、開始日、予定日数 という列があります。

このテーブルからQUERY関数で F1セルに 担当者名が一致するデータを抽出したい。(F1セルが空欄の時は考慮不要)

その際、1~3列目はそのままで、4列目を 予定日数ではなく3列目の開始日(日付型)+4列目の予定日数(数値型) で終了日を出力したい。

この時どのようなQUERY関数の式を組めばよいでしょうか?

データは👇こちらをコピペして 「イベント計画表」というテーブルにして利用ください。

タスク名	担当者	開始日	予定日数
イベント企画	佐藤	2025/07/15	7
予算編成	鈴木	2025/07/15	3
プラットフォーム選定	佐藤	2025/07/18	5
講演者手配	田中	2025/07/20	10
プロモーション資料作成	鈴木	2025/07/25	7
参加登録ページ作成	佐藤	2025/07/28	5
テクニカルテスト	佐藤	2025/08/05	3
プロモーション開始	鈴木	2025/08/01	15
イベント運営マニュアル作成	田中	2025/08/10	5
事後アンケート作成	加藤	2025/08/15	3

QUERY関数の外で日付を処理する方法もありますが、今回は先ほどのエポックミリ秒変換のヒントを元に QUERY関数内での日付加工にチャレンジしてみましょう!









↓↓
回答はここから。

↓↓





A1. QUERY関数で 開始日と予定日数から終了予定日を計算して出力したい

回答です。

=QUERY(イベント計画表[#ALL],
"select Col1,Col2,Col3,
toDate((dateDiff(Col3,date '1970-01-01')+Col4)*24*60*60*1000)
where Col2 = '"&F1&"'")

ポイントは 3行目の

toDate((dateDiff(Col3,date '1970-01-01')+Col4)*24*60*60*1000)

です。

解説していきましょう。


dateDiff(Col3,date '1970-01-01')

まず、エポックミリ秒の開始日である 1970/01/01から 3列目の開始日までの日数を dateDiff() を使って取得します。

ここで 第2引数の方に入れる 1970/01/01 は date '1970-01-01' と、日付リテラルで記述します。


dateDiff(Col3,date '1970-01-01')+Col4

この時点で日数(数値型)になっているので、4列目の終了までの予定日数を加算しちゃいます。

これで 1970-01-01から終了日までの日数の数値となりました。


(dateDiff(Col3,date '1970-01-01')+Col4)*24*60*60*1000

これをカッコで括って *24*60*60*1000 とすることで 終了日のエポックミリ秒に変換します。


toDate((dateDiff(Col3,date '1970-01-01')+Col4)*24*60*60*1000)

最後に toDate()で エポックミリ秒の数値を 日付型に変換すれば、終了日の日付となります。

開始日に予定日数を足した終了日を QUERY関数内で返すことが出来ました!


クエリの外で日付部分を処理する場合も手間はそれなりで、

=ARRAYFORMULA(QUERY({イベント計画表_3[#HEADERS];{イベント計画表_3[[タスク名]:[開始日]],TO_DATE(イベント計画表_3[開始日]+イベント計画表_3[予定日数])}},"where Col2 ='"&F1&"'"))

第1引数をコネコネする必要があります。

QUERY関数の内部で日付を+-する為の「エポックミリ秒変換」 理解できましたでしょうか?



Q2. QUERY関数内で今現在の日本の日付を使いたい

エポックミリ秒変換を使った 超応用例をもう1問いってみましょう。

前回登場したスカラー関数の now() 。これはGMTベースである為、日本時間より9時間遅い 日時を返します。

この時差を調整した 日本の 現在時刻(日時) を返す ことはクエリ内の処理では非常に厳しいです。

これは エポックミリ秒を日時に変換する関数が無い為です。

ただ、Q1と同じ要領で 時差を調整した リアルタイムの日本の 日付であれば、クエリ内の処理で スカラー関数の now()から取得できます

これにチャレンジしてみましょう!


シート関数のNOWで取得した日時(日本時間)④ が 2025/07/13 7:17:49 の時、QUERY関数の now()が返す 現在時刻(GMT) ① は9時間前の前日 2025/7/12 22:17:49 となっています。


ここでネックになるのが 日本時間が0時~9時の間は、GMT基準とは日付が1日ズレる点。

QUERY関数の now()を toDate()で日付にした ②が 2025/07/12 

シート関数のTODAY ⑤ が 2025/07/3

このように1日ズレてしまいます。

しかし、Q1と同じようにエポックミリ秒変換と算術演算子を活用することで、③のように QUERY関数 でも日本時間の今日の日付を返すことが出来ます。

この式を作ってみましょう。というお題です。
ただし秒単位の誤差は許与するものとします。

考えてみましょう!










↓↓
回答はここから。

↓↓





A2. QUERY関数内で今現在の日本の日付を使う式

回答です。

=QUERY(,"select toDate((dateDiff(now(),date '1970-01-01')*24*60 + (hour(now()) + 9 )*60 + minute(now()))*60*1000) ")

解説していきます。

dateDiff(now(),date '1970-01-01')

まず dateDiffでエポック開始日の 1970-01-01からGMTベースの現在の日付までの日数を算出します。(時、分、秒は切り捨てられる)


dateDiff(now(),date '1970-01-01')*24*60*60*1000

これをエポックミリ秒に変換
※これがGMTベースの現在の「日付」のエポックミリ秒


dateDiff(now(),date '1970-01-01')*24*60*60*1000
+ hour(now())*60*60*1000 + minute(now())*60*1000

dateDiff()で切り捨てられた 時・分の部分のエポックミリ秒を加算。

ここでスカラー関数の hour(), minute() を活用します。(秒の誤差は不問としているので分まででOK)

この結果は、GMTベースの現在時刻(分まで)のエポックミリ秒 となります。


dateDiff(now(),date '1970-01-01')*24*60*60*1000
+ (hour(now()) + 9)*60*60*1000 + minute(now())*60*1000

日本時間との時差の9時間を 時の部分に加算

※これが日本時間の現在時刻(分まで)のエポックミリ秒


(dateDiff(now(),date '1970-01-01')*24*60
+ (hour(now()) + 9 )*60 + minute(now()))*60*1000

*60*1000 の部分は全体にかかっているので式を整理


toDate((dateDiff(now(),date '1970-01-01')*24*60 + (hour(now()) + 9 )*60 + minute(now()))*60*1000)

最後に toDate() でエポックミリ秒を 日付型に変換

これが時差が調整された 日本時間の 本日の日付となっています!



これを活用すれば

7/13 8時に確認すると下の式は 7/15期限のタスクが拾えない 

前回のお題 で登場した 期限まで3日を切ったタスクを出力する QUERY関数で  dateDiff()とnow()を使った時は 朝9時前に確認すると 時差の影響で 取りこぼしがあったものが

今回の now() 日本時間変換式を使うことで

このように上の シート関数のTODAY()を使った式と同じ正しい結果を得ることができるようになります。



エポックミリ秒変換って覚えた方がいいの?

はっきり言ってしまえば覚える必要はありません

たぶん今回の解説も一部の人には「おー」って感じでしょうが、ほとんどの人が「なんでこんなことを?」って処理かと思いますw


とにかく式が

=QUERY(当番表[#ALL],"where Col4 != '完了' and dateDiff(Col3,toDate((dateDiff(now(),date '1970-01-01')*24*60 + (hour(now()) + 9 )*60 + minute(now()))*60*1000) ) < 3 ")

👆このように複雑かつ長くなってしまいうので、 結局シート関数のTODAY関数を使ってクエリ文の外側で処理をした 👇 こっちの式の方が

=QUERY(当番表[#ALL],"where Col4 != '完了' and dateDiff(Col3,date "&TEXT(TODAY(),"'yyyy-MM-dd'")&") < 3 ")

短くてわかりやすいんですよね。

エポックミリ秒変換は、あまり実用的とは言えないかも・・・。

使えそうな機会があれば、このnoteで学んだことを思い出してください。



4. 日付・日時・時刻で文字列比較演算子を使う方法を理解する

QUERY関数で日付・日時・時刻を扱うポイントの最後、その4は 文字列比較演算子を使う方法です。

文字列比較演算子は where句の回で登場した

$$
\begin{array}{ll}
\text{複雑な文字列比較演算子}&\text{解説}\\ \hline
\text{contains}&\text{〇〇を含む}\\ \hline
\text{starts with}&\text{〇〇から始まる}\\ \hline
\text{ends with}&\text{〇〇で終わる}\\ \hline
\text{like}&\text{ ワイルドカードを使った一致判定}\\ \hline
\text{matches}&\text{正規表現を使った一致判定}\\ \hline
\end{array}
$$

この5つですね。

QUERY関数8 where句の 複雑な文字列比較演算子 の基本

「文字列」比較演算子ですが、公式にも

Where 句では、より複雑な文字列比較演算子もサポートされています。これらの演算子は 2 つの文字列を引数として受け取り、文字列以外の引数(日付や数値など)は比較前に文字列に変換されます

とある通り、これらは日付や日時・時刻の型に対しても利用できます

QUERY関数9 文字列比較演算子を 文字列以外で活用する

そして 日付や日時を 文字列比較演算子で使いこなせることが、QUERY関数の日付・日時・時刻を極める上では必須といえます!



日付・日時・時刻を 文字列化した時の中身

まず 日付・日時・時刻 を文字列演算子で使うにあたり、文字列化した時の中身がどうなっているか?を確認していきましょう。

ブール値も シート上は TRUE, FALSE となっていますが、文字列比較演算子で扱う場合は  true, false だったりと、見た目と文字列化した中身は違うことが往々にしてあります。

文字列比較演算子を文字列型以外の列で使う際の注意点

文字列化したデータをQUERY関数で出力することは出来ませんが、likeをワイルドカード無しで使う一致判定で探ることは出来ます。

例として 2025/07/01 という日付データ を 対象に

'2025/07/01'

'2025-07-01'

が文字列比較演算子で 一致となるか試してみましたが、見出し行のみの出力となり一致となりません。

ここで日付は likeで条件として使えないのかと諦めてはいけません。

実は 日付を文字列化したものは、ハイフン区切りの0埋めなしの文字列となっているんです。

つまり 2025/07/01 の文字列化した中身は '2025-7-1' ってことです。

=QUERY(A2:D3,"where Col1 like '2025-7-1'")

リテラルだと date 'yyyy-MM-dd' なのに(0埋めなしでも可)、こっちは0無しだったとは・・・。

同じく日時は

=QUERY(A2:D3,"where Col2 like '2025-7-1 9:8:0.0'")

日付部分の後ろに半角スペースを入れて、時、分、秒、ミリ秒も含めた 0埋めなしの表記。

特殊なのが シート上の時刻型 の文字列化で、こちらは

=QUERY(A2:D3,"where Col3 like '1899-12-30 7:1:2.0'")

時刻のみではヒットせず、日付部分に 1899-12-30 (シリアル値 0の日付)を入れた日時型の表記にする必要があります。

まとめると

■文字列比較演算子で日付・日時・時刻を文字列と見なして扱う時の表記
日付 'yyyy-M-d'
日時 'yyyy-M-d H:m:s.S'
時刻 '1899-12-30 H:m:s.S'

ミリ秒のSの部分はTEXT関数で指定する際は 0 とします 

このようになっています。

これを活用したお題にチャレンジしてみましょう!



Q3. QUERY関数で文字列比較演算子 likeを使って指定した年、月のデータだけを抽出したい

1つ目のお題はこちら。

1列目の日付データを対象に年、月を指定して QUERY関数で絞り込みをしたいというお題です。

G1の年、G2の月を参照する 前回 スカラー関数のyear(), month()+1 を使って解いたお題ですが、今度は文字列比較演算子 like を使う方法でチャレンジしてみましょう!

👇サンプルデータはこちら。

付	日時	時刻	テキスト
2025/07/01	2025/07/01 10:45	10:45	A
2025/07/02	2025/07/02 11:30	11:30	B
2025/12/12	2025/12/12 14:22	14:22	A
2026/01/22	2026/01/22 16:01	16:01	A
2025/07/05	2025/07/05 17:11	17:11	B
2025/07/06	2025/07/06 18:50	18:50	B
2026/02/20	2026/02/20 21:40	21:40	A

第1引数は A1:D8 と指定、G1、G2が空白の時の考慮は不要とします。可能な限り短い式を目指しましょう!










↓↓
回答はここから。

↓↓





A3. QUERY関数で文字列比較演算子 likeを使って指定した年、月のデータだけを抽出する

回答です。

=QUERY(A1:D8,"where A like '"&G1&"-"&G2&"-%'")

46文字。式を短くするために Col1ではなく A で列指定

かなりシンプルですね。


前回のスカラー関数を使った式だと

=QUERY(A1:D8,"where year(Col1) = "&G1&" and month(Col1) + 1 = "&G2)

年、月それぞれを一致判定する式を and で結ぶ必要があるんで、どうしても長くなってしまいます。

回答の中でポイントとなるのは、

文字列として比較するので、'(シングルクォート)で前後を括るという点。

そしてもう一つ 

👆 G2(月)の後ろにも - を入れる点。

日付の「日」の部分は 何日でもいいので ワイルドカードの %を使うのはわかりますね?

ただ、例えば G1の年が2025、G2の月が1 だった場合、G2の後ろの - が無いと

A like '2025-1%'

このようになるのですが、これは

1月だけでなく1から始まる 11月や12月もヒットしてしまいます。

G2&"-%'

と - を月の後ろにも入れて区切り位置を明示することで、これを防止しています。


あまり使う機会は無いかと思いますが、日時の列を対象として 時、分を指定して where句で抽出するケースも紹介しておきましょう。

=QUERY(A1:D8,"where Col2 like '% "&G1&":"&G2&":%'")

likeを使う場合は G1(時)の前に '% "& と %の後ろに日付と時刻部分の間の半角スペースを含めることと、G2(分)の後ろに秒の前の : を入れる点。

これを忘れると 2時を指定したつもりが 21時や22時もヒットしてしまったり、3分を指定したはずが 31~39分まで全部ヒットしてしまうという誤判定が発生します。


もう1問、応用問題にチャレンジしてみましょう!



Q4. QUERY関数で文字列比較演算子 likeを使って指定した年、月、日 のデータだけを抽出したい。ただし年、月、日のセルが空の場合は その部分は条件無しとしたい

A:Bが画像のようなデータだった場合、D2,E2,F2 セル年、月、日の数値を入れた時に QUERY関数で該当する日付のデータだけを抽出したい。というお題です。

ただし年、月、日の セルが空白だった場合は、その箇所は条件なしとします。

つまり、画像のように月が10で 年、日が 空欄の場合は 年や日を気にせず10月のデータを全て出力するということです。

当然、年、月、日 を全て数値を入れた場合は

全て一致する日付データのみを抽出します。逆に全部空白の場合は全データを返します。

サンプルデータ生成式として 👇以下の式をA1に入れて利用ください。(この式の説明は割愛)

=ARRAYFORMULA(LET(
  n,200,d,"2025/07/01",sn,SEQUENCE(n),
  {"日付","区分";TO_DATE(sn+d-1),CHAR(MOD(sn-1,26)+65)}
))

出来るだけ短い式を考えてみましょう!










↓↓
回答はここから。

↓↓





A4. QUERY関数で文字列比較演算子 likeを使って指定した年、月、日 のデータだけを抽出したい。ただし年、月、日のセルが空の場合は その部分は条件無しとする

回答です。

=QUERY(A:B,
"where Col1 like '"&INDEX(JOIN("-",TEXT(D2:F2,"0;;%"))&"'"))

👆こちらの式に近い式は作れましたでしょうか?

ポイントは

  1. 比較演算子 like で日付を文字列として判定する

  2. D2:F2は配列として処理。ARRAYFORMULAの代わりにINDEXを利用

  3. IFで分岐させずにTEXT関数の表示形式の条件分岐を利用

  4. JOINで - を区切り文字として配列を連結

この4点です。

ポイント1の lkieを使う方法は、先ほどのお題3でやったので大丈夫ですね。

ただ、お題3はセルが空白時の考慮は不要でしたが、今回は年・月・日のセルが空白だった時に条件なしとする必要があります。

条件なしとする方法は お題3で 日付部分を % (ワイルドカード)にしたのと同じ方法です。

例えば E2(月)だけ10と入っていた場合は、 Col1 like '%-10-%' を生成すればOKってことです。

各セル毎に 数値が入っていればそのまま数値を、空だった場合は %を返すとしたいのですが、これを配列処理する為に ARRAYFORMULAが必要になります。

ただ ARRAYFORMULAだと文字数が多いので、同じ効果があってより短い関数である INDEX関数で代替したわけです。これがポイント2です。

ARRAYFORMULAを完全に代替できる INDEX関数


さらに、普通はIF関数を使う分岐処理ですが

D2:F2を2回書くことになるので、ここを見直したいと考えます。

ここで使えるのが ExcelやGoogleスプレッドシートの

正の数; 負の数; ゼロの時; 文字列

4つのパターンで動的に表示形式を設定できるという仕様です。

Googleスプレッドシート カスタム数値形式

これはTEXT関数でも利用ができます。

TEXT関数で数値の表示形式を設定した場合、空白は0として扱われるので、今回はこれを利用します。

TEXT関数の表示形式分岐を使う際は、

☑結果が文字列型になる
☑空白と 0 と切り分けが必要
☑マイナス数値の際の表記も記述が必要

など幾つか考慮が必要なんですが、今回は年、月、日なので 0やマイナスの数値が入るケースの考慮が不要なので、TEXT関数がハマります。

TEXT(D2:F2,"0;;%")

このように記述し

正の数の時 0 ・・・ そのまま数値を返す
負の数の時 空白 ・・・ 考慮不要
0の時 % ・・・ 空白時と判定。ワイルド―カード%を返す

とすることで IFの代替して利用して

式を 4文字削減しています。これがポイント3です。

この方法は QUERY関数のselect句の時にも登場しましたね。

セルでカンマ区切りで列番号の数字を入れた列を、その順番でQUERY関数で出力する


最後に加工した配列を - で連結して一つの文字列とするのですが、ここで TEXTJOIN関数ではなく引数がシンプルで関数名も短い JOIIN 関数を使うのが ポイント4です。


もし、これを空白の時はIFで分岐させて、スカラー関数で年、月、日のそれぞれの一致を判定させて and で連結させようとすると、

=QUERY(A:B,"where
year(Col1) = "&IF(D2="","year(Col1)",D2)&
" and month(Col1)+1 ="&IF(E2="","month(Col1) + 1",E2)&
" and day(Col1) = "&IF(F2="","day(Col1)",F2)
)

式の長さは倍以上になります。

そもそも、こっちの式も作れる人はだいぶ限られる複雑さじゃないでしょうか?

starts withcontains など他の文字列比較演算子も日付を条件とした抽出に使えるんですが、一致判定が出来て 一番シンプルに使えるのが likeです。

QUERY関数の where句で 日付データを扱う場合は、文字列比較演算子 likeが 超絶便利!

伝わりましたでしょうか?



Q5. QUERY関数で セル範囲に記述した複数の日付のいずれかに一致するを条件でデータを抽出したい

最後に正規表現が使える 文字列比較演算子 matches を使った複数の日付を OR条件で一致判定する お題にチャレンジしてみましょう。

お題4と同じデータがA:Bにあります。D列の2行目以降のセルに 候補日として幾つか日付を入れた場合、D2:Dのいずれかの日付に1列目が一致するデータをQUERY関数で抽出したい場合、どのような式を組めばよいでしょうか?

なお候補日の数は変動するものとします。

これは likeでは対応が難しいケースです。考えてみましょう!











↓↓
回答はここから。

↓↓






A5. QUERY関数で セル範囲に記述した複数の日付のいずれかに一致するを条件でデータを抽出する

回答です。

=QUERY(A:B,"where Col1 matches '"&
ARRAYFORMULA(JOIN("|",TEXT(TOCOL(D2:D,1),"yyyy-m-d")))&"'")

これまでの応用ですね。解説していきます。


まず QUERY関数シリーズの9で 登場した 

where句の matchesで 複数の値のいずれかに「一致する」記述と、いずれかを「含む」記述

複数の値のいずれかに「一致する」という条件の記述
matches 'apple|car|free|zoo'

こちらを今回の 日付のケースにあてはめます。

セルに入った日付は そのまま利用できないので、TEXT関数で成形する必要があることはQUERY関数シリーズ11 日付リテラルの回で学びましたね。

A2. セルの日付をwhere句の条件にする

文字列比較演算子で使用する場合は、TEXT関数で文字列化の加工をする際に

"yyyy-m-d"

と0埋めなしにします。ここは注意ポイント。

そしてもう1つの注意点が、範囲が D2:D となる点です。

空白セルは 通常であれば TEXTJOIN関数で 第2引数を TRUEとすることで除外できるんですが、

今回の場合はTEXTJOINの前に 各セルの値をTEXT関数で加工する為

空白セルが シリアル値0として扱われ 1899-12-30 となってしまいます。

このままTEXTJOINで連結すると無駄に 1899-12-30 の繰り返しが連結されることになり計算負荷が上がりますし、行数が多い場合はTEXTJOINの上限エラーとなってしまう可能性も。

ここはTEXT関数に渡す前に空白セルを処理しちゃいましょう。

Excelなら トリム演算子ですが、Googleスプレッドシートには無いので TOCOL関数の第2引数1を利用します。

これによって無駄な空白セルが除外されてから、日付文字列に変換されます。

空白除去の必要がないので、連結はTEXTJOINではなく JOIN関数でOK

2025-7-19|2025-8-5|2025-9-30|2025-12-21|2026-1-3

👆 matchesの「いずれかに一致する」で使える パイプ区切りの日付文字列が出来上がりました。


"where Col1 matches '"&
ARRAYFORMULA(JOIN("|",TEXT(TOCOL(D2:D,1),"yyyy-m-d")))&"'"

あとは前後の シングルクォートを忘れずに!

ここまでの理解が出来ていれば簡単でしたかね。

ちなみに「いずれも含まない」を条件に抽出したい場合は


=QUERY(A:B,"where not Col1 matches '"&
ARRAYFORMULA(JOIN("|",TEXT(TOCOL(D2:D,1),"yyyy-m-d")))&"'")

頭に not をつけるだけです。



QUERY関数で 日付・日時・時刻を極める

3週にわたり、QUERY関数で 日付・日時・時刻を扱う為の 4つのポイントを学びました。

  1. 日付・日時・時刻のリテラル 記述ルールを理解する

  2. 日付・日時・時刻で比較演算子が使えることを理解する

  3. 日付・日時・時刻を加工できるスカラー関数を理解する 👈今回応用

  4. 日付・日時・時刻で文字列比較演算子を使う方法を理解する 👈今回理解


新しい発見や学びはありましたでしょうか?

QUERY関数の日付、日時、時刻の扱いを極めて、次に登場する group bypivot句による 集計でも 使いこなせるようになっていきましょう!

2,3週違うネタを挟んでから、QUERY関数シリーズの続きを書きたいと思います。


いいなと思ったら応援しよう!

mir チップ大歓迎です。やる気がアップしますw