痛いです。とても痛いです。
この問題についての質問は明確ではありませんが、参照している「ユーザーID」はユーザー名であると想定しています。それが間違っている場合は、結果的に変更を加える必要があります。
他の複雑なクエリと同様に、段階的に構築します。
ステージ1:レコードごとにnull以外のフィールドはいくつありますか?
SELECT username, sex, date_of_birth, zip,
CASE WHEN sex IS NULL THEN 0 ELSE 1 END +
CASE WHEN date_of_birth IS NULL THEN 0 ELSE 1 END +
CASE WHEN zip IS NULL THEN 0 ELSE 1 END AS num_non_null_fields
FROM users_log
ステージ2:特定のユーザー名のフィールドの最大数はどれですか?
SELECT username, MAX(num_non_null_fields) AS num_non_null_fields
FROM (SELECT username, sex, date_of_birth, zip,
CASE WHEN sex IS NULL THEN 0 ELSE 1 END +
CASE WHEN date_of_birth IS NULL THEN 0 ELSE 1 END +
CASE WHEN zip IS NULL THEN 0 ELSE 1 END AS num_non_null_fields
FROM users_log
) AS u
GROUP BY username
ステージ3:null以外のフィールドの最大数を持つ特定のユーザーの行を(すべて)選択します:
SELECT u.username, u.sex, u.date_of_birth, u.zip
FROM (SELECT username, MAX(num_non_null_fields) AS num_non_null_fields
FROM (SELECT username, sex, date_of_birth, zip,
CASE WHEN sex IS NULL THEN 0 ELSE 1 END +
CASE WHEN date_of_birth IS NULL THEN 0 ELSE 1 END +
CASE WHEN zip IS NULL THEN 0 ELSE 1 END AS num_non_null_fields
FROM users_log
) AS u
GROUP BY username
) AS v
JOIN (SELECT username, sex, date_of_birth, zip,
CASE WHEN sex IS NULL THEN 0 ELSE 1 END +
CASE WHEN date_of_birth IS NULL THEN 0 ELSE 1 END +
CASE WHEN zip IS NULL THEN 0 ELSE 1 END AS num_non_null_fields
FROM users_log
) AS u
ON u.username = v.username AND u.num_non_null_fields = v.num_non_null_fields;
これで、(たとえば)3つのフィールドすべてが入力された複数の行がある場合、それらのすべての行が返されます。ただし、これらの行から選択するための基準は指定していません。
ここでの基本的な手法は、変更された要件に適合させることができます。重要なのは、サブクエリを作成してテストすることです。
このSQLはどれもDBMSの近くにはありません。バグがある可能性があります。
使用しているDBMSを指定していません。ただし、Oracleは、列エイリアスのASに問題はありませんが、テーブルエイリアスに使用されるAS表記を好まないようです。他のDBMSを使用している場合は、その小さな偏心について心配する必要はありません。