Vai ser doloroso; muito doloroso.
Sua pergunta não é clara sobre esse problema, mas estou assumindo que o 'id de usuário' ao qual você está se referindo é o nome de usuário. Há modificações consequentes a serem feitas se isso estiver errado.
Como em qualquer consulta complexa, construa-a em etapas.
Estágio 1:Quantos campos não nulos existem por registro?
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
Etapa 2:Qual é o número máximo de campos para um determinado nome de usuário?
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
Etapa 3:selecione (todas) as linhas de um determinado usuário com esse número máximo de campos não nulos:
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;
Agora, se alguém tiver várias linhas com (digamos) todos os três campos preenchidos, todas essas linhas serão retornadas. No entanto, você não especificou nenhum critério para escolher entre essas linhas.
As técnicas básicas aqui podem ser adaptadas a quaisquer requisitos alterados. A chave é construir e testar as subconsultas à medida que avança.
Nenhum desses SQL chegou perto de um DBMS; pode haver bugs nele.
Você não especificou qual DBMS está usando. No entanto, parece que o Oracle não gostará da notação AS usada para aliases de tabela, embora não tenha problemas com AS em aliases de coluna. Se você estiver usando qualquer outro DBMS, não precisa se preocupar com essa pequena excentricidade.