Notes

集計から1名だけ
消えていた話

提出用の集計を作っていて、同じ回答データから出したはずの2つの数字が5,937名と5,938名になりました。1名だけ合いません。

「まあ1名だし」で済ませられない仕事です。報告書に載る母数が2種類あるのは、 その報告書全体の信用に関わります。

消えていたのは、深夜2時に回答した人

差分を取ると、参加者番号がひとつ特定できました。回答時刻は8月1日の午前2時1分です。

この企画には「最終日の翌朝3時まで有効」という設定が入っていました。 飲食店の企画なので、7月31日の夜に入った人が日付をまたいで会計することがある。 そのため、7月31日の営業日は8月1日の3時までとして扱っています。

この人はルール上は7月31日の参加者です。 画面もそのように動いていて、実際にクーポンを使えています。

片方の集計だけが暦の月で数えていた

ところが月別の集計は、素直に暦の月でバケツ分けしていました。

to_char(created_at at time zone 'Asia/Tokyo', 'YYYY-MM')

これだと午前2時の回答は「2026-08」に入ります。 そして、この企画の期間は7月だけなので、集計対象の月の一覧に「2026-08」がない。どのバケツにも入らなかった行は、そのまま捨てられていました。

エラーは出ません。警告も出ません。合計が1つ少ないだけです。 もう一方の集計(クロス集計)は別の実装で、期間で絞ってから数えていたので こちらは正しく5,938名でした。

本当の原因は「片側だけ直した」こと

深夜まで有効にする仕組みを入れたとき、直したのは「クーポンを使えるかどうか」の判定だけでした。 同じ「期間」という言葉を使っている集計側は、そのままになっていた。

期間の定義を変えるというのは、その期間で何かを数えている場所すべてに影響します。 利用の可否、月別の集計、週別の推移、報告書の母数、精算の対象。 このときは最初の1つしか直していませんでした。

直し方は、日付を決める関数を1つにする

「この記録は、企画上のどの日に属するか」を返す関数を作り、 期間で数える場所は全部そこを通すようにしました。 最終日の翌日でも、設定した時刻より前なら最終日として数えます。

単体テストは、境界だけを狙って書きました。 クロージング時刻ちょうど、1分後、翌々日、設定なし、24:00指定。 こういう箇所は、真ん中の値をいくつ試しても意味がありません。

直したあと、月別の集計も5,938名になり、2つの数字が一致しました。

この件から続けていること

  • バケツから落ちた件数を必ず突き合わせる。月・週・エリアなどで分ける処理は、分けたあとの合計と元の件数を比べる。 合わなければ、どこにも入らなかった行がある
  • 同じ数字を2つの経路で出せるようにしておく。今回ずれに気づけたのは、たまたま別実装の集計があったからです。 1つしか無ければ、間違ったまま提出していました
  • 「期間」の定義を変えたら、期間で数えている場所を洗い出す。片側だけ直すのは、直さないより厄介です。動いているように見えてしまうので

報告書の作り方はアンケートのクロス集計から報告書PDFを自動生成するまで、 精算での数字の扱いは精算に書いています。

ほかの開発記録

ハレポンは、ここに書いた仕組みをそのまま使えるクーポン発行システムです。 企画設計から報告書の提出までお引き受けしています。できること料金もご覧ください。

資料をダウンロード相談する