Ini akan menyakitkan; sangat menyakitkan.
Pertanyaan Anda tidak jelas tentang masalah ini, tetapi saya berasumsi bahwa 'user id' yang Anda maksud adalah nama pengguna. Ada modifikasi konsekuensial yang harus dilakukan jika itu salah.
Seperti halnya kueri kompleks lainnya, buatlah secara bertahap.
Tahap 1:Berapa banyak bidang non-null yang ada per catatan?
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
Tahap 2:Berapa jumlah kolom maksimum untuk nama pengguna tertentu?
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
Tahap 3:Pilih (semua) baris untuk pengguna tertentu dengan jumlah maksimum bidang bukan nol:
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;
Sekarang, jika seseorang memiliki beberapa baris dengan (katakanlah) ketiga bidang terisi, maka semua baris itu akan dikembalikan. Namun, Anda belum menentukan kriteria apa pun untuk memilih di antara baris tersebut.
Teknik dasar di sini dapat disesuaikan dengan persyaratan yang berubah. Kuncinya adalah membangun dan menguji sub-kueri saat Anda melanjutkan.
Tak satu pun dari SQL ini telah dekat dengan DBMS; mungkin ada bug di dalamnya.
Anda belum menentukan DBMS mana yang Anda gunakan. Namun, sepertinya Oracle tidak akan menyukai notasi AS yang digunakan untuk alias tabel, meskipun tidak ada masalah dengan AS pada alias kolom. Jika Anda menggunakan DBMS lain, Anda tidak perlu khawatir tentang eksentrisitas kecil itu.