Ça va être douloureux; très douloureux.
Votre question n'est pas claire à propos de ce problème, mais je suppose que "l'identifiant d'utilisateur" auquel vous faites référence est le nom d'utilisateur. Il y a des modifications consécutives à faire si c'est faux.
Comme pour toute requête complexe, construisez-la par étapes.
Étape 1 :Combien de champs non nuls y a-t-il par enregistrement ?
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
Etape 2 :Quel est le nombre maximum de champs pour un nom d'utilisateur donné ?
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
Étape 3 :Sélectionnez (toutes) les lignes pour un utilisateur donné avec ce nombre maximal de champs non nuls :
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;
Maintenant, si quelqu'un a plusieurs lignes avec (disons) les trois champs remplis, alors toutes ces lignes seront renvoyées. Cependant, vous n'avez spécifié aucun critère permettant de choisir entre ces lignes.
Les techniques de base ici peuvent être adaptées à toute modification des exigences. La clé est de créer et de tester les sous-requêtes au fur et à mesure.
Aucun de ces SQL n'a été proche d'un SGBD ; il pourrait y avoir des bugs.
Vous n'avez pas spécifié le SGBD que vous utilisez. Cependant, il semble qu'Oracle n'aime pas la notation AS utilisée pour les alias de table, bien qu'il n'ait aucun problème avec AS sur les alias de colonne. Si vous utilisez un autre SGBD, vous ne devriez pas avoir à vous soucier de cette excentricité mineure.