Det vil være smertefuldt; meget smertefuldt.
Dit spørgsmål er ikke klart om dette problem, men jeg antager, at det 'bruger-id', du henviser til, er brugernavnet. Der er konsekvensændringer at foretage, hvis det er forkert.
Som med enhver kompleks forespørgsel skal du bygge den op i etaper.
Trin 1:Hvor mange felter, der ikke er nul, er der pr. post?
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
Trin 2:Hvad er det maksimale antal felter for et givet brugernavn?
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
Trin 3:Vælg (alle) rækkerne for en given bruger med det maksimale antal felter, der ikke er nul:
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;
Nu, hvis nogen har flere rækker med (f.eks.) alle tre felter udfyldt, så vil alle disse rækker blive returneret. Du har dog ikke angivet nogen kriterier for at vælge mellem disse rækker.
De grundlæggende teknikker her kan tilpasses til eventuelle ændrede krav. Nøglen er at bygge og teste underforespørgslerne, mens du går.
Intet af denne SQL har været i nærheden af et DBMS; der kan være fejl i den.
Du har ikke angivet, hvilket DBMS du bruger. Det ser dog ud til, at Oracle ikke vil kunne lide AS-notationen, der bruges til tabelaliasser, selvom det ikke har noget problem med AS på kolonnealiaser. Hvis du bruger et hvilket som helst andet DBMS, skal du ikke bekymre dig om den mindre excentricitet.