To będzie bolesne; bardzo bolesne.
Twoje pytanie nie jest jasne dotyczące tego problemu, ale zakładam, że „identyfikator użytkownika”, do którego się odnosisz, to nazwa użytkownika. Jeśli to źle, należy wprowadzić modyfikacje.
Podobnie jak w przypadku każdego złożonego zapytania, twórz je etapami.
Etap 1:Ile pól innych niż null znajduje się w rekordzie?
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
Etap 2:Jaka jest maksymalna liczba pól dla danej nazwy użytkownika?
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
Etap 3:Wybierz (wszystkie) wiersze dla danego użytkownika z maksymalną liczbą pól innych niż 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;
Teraz, jeśli ktoś ma wiele wierszy z (powiedzmy) wypełnionymi wszystkimi trzema polami, wszystkie te wiersze zostaną zwrócone. Jednak nie określiłeś żadnych kryteriów wyboru między tymi wierszami.
Podstawowe techniki można tutaj dostosować do wszelkich zmienionych wymagań. Kluczem jest budowanie i testowanie podzapytań na bieżąco.
Żaden z tych SQL nie był w pobliżu DBMS; mogą być w nim błędy.
Nie określiłeś, którego DBMS używasz. Wydaje się jednak, że Oracle nie spodoba się notacja AS używana do aliasów tabel, chociaż nie ma problemu z AS na aliasach kolumn. Jeśli używasz innego DBMS, nie powinieneś się martwić o tę drobną ekscentryczność.