ProgrammingBI/アナリスト, データエンジニア

NULLや重複を考慮した複雑な基準に基づくユニークユーザーのカウントを、SQLのDISTINCT、COUNT、GROUP BY構文を使用して正しく実装するにはどうすればよいですか?

Hintsage AIアシスタントで面接を突破

回答。

質問の歴史

ユニークユーザーに関するレポートは分析や統計に必要です。しかし、実際のデータにはしばしばアカウントの重複やNULL値(たとえば、未指定のメールアドレス)があり、さまざまな基準(たとえば、名前、メール、IPによるユニーク性、時にはそれらの組み合わせ)を考慮する必要があります。

問題

一般的な誤りは、必要な列にNULLがあることを考慮せずにCOUNT(DISTINCT user_id)をカウントすることです。異なるメールアドレスを持つ同一人物や、同じuser_idを持つ複数の行と異なるステータスなど、明示的でない重複を考慮する必要があります。GROUP BYを使った複雑なクエリは、ユニーク性の論理が考慮されていないと不正確な結果を出す可能性があります。

解決策

DISTINCT、GROUP BY、およびNULLのフィルタリングを組み合わせることが重要です。場合によっては、CTEやネストしたサブクエリでデータを前処理し、必要な特徴の集合でグループ化する必要があります。

コード例:

-- NULLを無視してメールアドレスとIPによるユニークユーザーをカウント SELECT COUNT(*) AS unique_users FROM ( SELECT DISTINCT email, ip_address FROM users WHERE email IS NOT NULL AND ip_address IS NOT NULL ) u;

主な特徴:

  • DISTINCTは、列のいずれかにNULLがある行を考慮しません
  • クロスグループ化には、フィールドの組み合わせでGROUP BYを使用するのが最適です
  • 重複に取り組む場合、データを「クリーニング」する必要があることが多いです

答えが難しい質問。

COUNT(DISTINCT ...)はNULLがある行を考慮しますか?

いいえ:DISTINCTリストのいずれかの列がNULLの値を持つ場合、その組み合わせは別のユニークとしてカウントされます(SQL標準ではNULLはNULLに等しくありません)。通常は、NULLをフィルタリングで最初に削除する方が便利です。


NULLをDISTINCTでNULLと比較できますか?

SQLでは、各NULL値のペアは異なるものとみなされるため、任意の列にNULLがある各行は別々のものとしてカウントされます。IS NOT NULLでフィルタリングする必要があります。


GROUP BYは常にDISTINCTと同じ結果を出しますか?

いいえ:GROUP BYは、重複しない値の組み合わせごとに1行を作成し、DISTINCTは単に重複を削除します。集計を使用する場合など、さまざまなケースで結果が異なることがあります。

一般的なエラーとアンチパターン

  • NULL値のフィルタリングの不明瞭さ
  • 集計前のデータの暗黙的な重複
  • 異なる階層レベルでのDISTINCTと集計の不正確な組み合わせ

生活の例

ネガティブケース

ビジネスアナリストはCOUNT(DISTINCT user_id)を使用してユニーククライアントのレポートを作成しますが、実際にはuser_idがNULLである可能性や重複が存在します(たとえば、一時的なアカウント)。実際のユーザー数は実際よりも多くなり、レポートの指標が歪んでしまいます。

長所:

  • レポートが迅速に実装されます

短所:

  • 不正確なメトリクスによる不正確なビジネス決定

ポジティブケース

アナリストは事前にデータをクリーニングし、NULLや明示的な重複をサブクエリでフィルタリングし、複雑なユニーク性の基準に対してSET演算を使用します。

長所:

  • 正確で透明なメトリクス
  • 妥当なビジネス決定とKPI

短所:

  • より複雑なクエリ、テストデータでの質のチェックが必要