集計結果がおかしいと思った時のチェックリスト
結果は出てきたが、何かおかしい気がする・・・そんな時のチェックリスト
データを準備して、ツールに投入して実行したら、予想していたのとは大分違う結果が出てきて戸惑う、なんてことは日常茶飯事だが、その際どうやって検証したらよいかについてまとめた。
入力データが間違えている
正しいデータを使っているつもりだったのに調べてみたら間違っていたというのが最も多いだろう。その内容も様々である。
チェック漏れ
データを受け取ったらチェックすることは必要だが、それでもチェックから漏れているかもしれないので改めて確認する。チェック項目は
- 欠損値
- 異常値
- 先頭の0が消えている
- 桁がおかしい
- 文字コード
- 重複
- データが足りない/多すぎる
など。
いつの間にかにデータの仕様が変わっている
相手のリテラシーが低いと定期的に受け取っているはずのデータなのになぜか突然仕様が変わっていることがあるので、調べても間違いがわからなかったら受け取ったデータを疑う。定期的にデータを受け取る際に気を付けることが大事。
取り込むテーブル名・ファイル名が違う
コードを使いまわししているとありがちだが、名称を変更し忘れていてデータが取り込めていなかったり、古いデータを取り込んでいるのに気が付かなかったりすることがある。
ファイル名は正しいが内容が違う
前処理などでファイルをいじったりしていると起きる。ファイル名は正しいのだが、うっかり古いファイルを新しいファイル名で上書きしてしまうケース。データの形式が同じだとエラーにならずそのまま実行されてしまい、違う結果が出ていることに気が付きづらいので危険。
取り込みを失敗している
正しいデータであっても正しく取り込めないと結果がおかしくなる。取り込めているかは都度確認が必要。
テスト時に制限した値が残ったままになっている
最初から全部取り込むのではなく、まず試しにいくらか取り込んで中身を確かめることは基本である。が、確認したあと制限を外すのを忘れてそのままにしてしまうことがある。コードの最初であれば見つけやすいが、コードの途中に紛れ込んでいると、見逃しやすい。
途中でおかしなデータがあってエラーを起こしている
仕様は正しいのだけれども、想定していないnullや0のせいでおかしくなっている。
コードの途中がおかしい
エラーで止まる場合はコードがおかしいとなるが、エラーにならずに結果がかえって来ると間違っていないと思い込みやすい。
範囲指定が違う(年度とか)
コードの途中に直接書き込む形式になっていたりすると地雷。他人が作ったコードの場合はなおさら面倒。見つけたらその時に修正しよう。あとでやろうとすると忘れる。
テーブルの結合
INNERJOINで件数が増えていないか
INNERJOINであれば2つのテーブルの共通部分が取られるので件数は同じか減るはずだが、なぜか結果はもとのテーブルより増えていることがある。これは通常意図した結果ではない。原因は結合キーが「2つのテーブルの双方で」重複しているからだ。IDでの絞り込みのように、結合キーが重複するべきでないのであればユニークになっているかを確かめる。レコードがユニークなのに結果が正しくなければIDと月の組み合わせで結合しなければならないところ、IDだけで結合してしまったのでIDが重複になっているというように結合キーを疑う。
LEFTJOIN(RIGHTJOIN)で件数が増えていないか
LEFTJOINについてはテーブルAにテーブルBをLEFTJOINしているならば、テーブルAの件数が得られるはずであるが、もし増えるようなことがあったテーブルBに結合キーの重複があるか、INNERJOINと同様に結合キーに不足がある。RIGHTJOINも同様。
フラグの立て違いはないか
IDに対してある種の条件を満たすかどうかのフラグ(商品の購入者フラグや除外対象者フラグ)を立てるというのはよくあるが、この時の条件を間違えるケースがままある。フラグを立て間違えると真逆の条件を指定することになりまったく違う結論になってしまうので危険度が高い。1・LEFTJOINかRIGHTJOINはどちらかしか使わないようにする、2・条件を見たす場合にフラグを立てる(is not null then 1)のか、あるいは満たさない場合にフラグを立てる(is null then 1)のどちらかしか使わないようにする、を自分(あるいはチーム内)で共有するのがおすすめ。
複数テーブルのJOINが遅くないか
複数テーブルのJOINを行う際、実行はオプティマイザーにより最適化される、とは言われるものの実際にどうなっているかはよくわからないところがある。3つのテーブルをIDをキーにしてINNERJOINすることを考えよう。1つのテーブルが100人程度の非常に小さいテーブル(例えばキャンペーンの当選者)、残り2つが大きいテーブル(会員マスタとPOSデータ)だとする。当然1つのSQLでまとめてJOINを書くことを考えるのだが、なぜかとても時間がかかる場合がある。
対処法は「100人のテーブルと会員マスタをまずJOINして、その次にPOSデータとJOINする」だ。このように小さいテーブルを先に作るようにしておけば、劇的に早くなることがある。おそらく大きなテーブル同士のJOINを行わなくて済むからだろうが、なぜそのように処理がされないのかはわからない。とはいえ早くなる方法があるならそちらを採用すべき。
ソート
ソートキーは正しいか
テーブルにあるカラム名ならselectになくてもエラーにならない。当初「都道府県」でソートしたところ空白や不正なデータがあったので「都道府県2」というカラムを作成し、クレンジングしたデータを入れたはずだがうまくソートがされていない。なぜかと言えばソートキーが「都道府県」のままだったからだった。
ソートした場合は意図した結果になっているかを最初の数件でもよいから確認する。油断してこの簡単な確認を怠ると、万が一の場合に支払うコストが高い。
昇順と降順は正しいか
よくありがちで、ソートの並び順が逆になっている。集計結果だったらあとでExcelでソートしなおせば済むが、スコアリングの結果上位100人を抽出する、という場合においては並び順が逆ではとんでもないことになる。これも目視で確認というのが確実。SQLに慣れているからとコードだけ見て結果を確認しないのは自分には怖くてできない。
その他考えられそうなこと
前回の処理で使ったデータをそのまま使ってしまった
ループなどで起きる。本来であればループごとに更新してそのデータを使わなければならないのに、最初の処理で設定されたデータがずっと使われて結果がかわってしまう。エラーになってくれれば探しやすいが、そうでない場合は間違えていることに気づきづらい。
実は途中で終わっていた/途中までしか実行していなかった
例えば5つのプロセスが終わらないと完了ではないのに、なんらかの理由で3つ目までで処理が終了していたがエラーがでない、あるいは勘違いでそこまでしか実行していないと最終結果には影響しない。1度目の実行であれば結果が無いのですぐわかるが、修正中など前回の結果が残っていると途中は修正したのに結果に反映されない。一部分を修正したら最初から最後まで全て実行できるならばそうするべきだが、時間の都合もあるので悩ましい。
結果が正しく予想が間違えている
実はコードは正しいのに、当初の予想が大きく間違えていたので違和感を持った、というような場合。危険なのはデータを入れてツールを動かしたのだから間違えていないと盲信してそこから無理矢理理解しようとすることで、事実を捻じ曲げてしまうのは最も行ってはいけない。ただし、この違和感は割と当たっていることも多いため慎重な判断が必要だ。
もっとありそうだけど
まずは思いついた内容を書きつらねてみた。他にもありそうなので、思いついたら追記しよう。