Nó sẽ rất đau đớn; rất đau đớn.
Câu hỏi của bạn không rõ ràng về vấn đề này, nhưng tôi giả định rằng 'id người dùng' mà bạn đang đề cập đến là tên người dùng. Có những sửa đổi do hậu quả để thực hiện nếu sai.
Như với bất kỳ truy vấn phức tạp nào, hãy xây dựng nó theo từng giai đoạn.
Giai đoạn 1:Có bao nhiêu trường không rỗng trên mỗi bản ghi?
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
Giai đoạn 2:Số lượng trường tối đa cho một tên người dùng nhất định là bao nhiêu?
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
Giai đoạn 3:Chọn (tất cả) các hàng cho một người dùng nhất định với số lượng trường không rỗng tối đa:
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;
Bây giờ, nếu ai đó có nhiều hàng với (giả sử) cả ba trường được điền, thì tất cả các hàng đó sẽ được trả về. Tuy nhiên, bạn chưa chỉ định bất kỳ tiêu chí nào để chọn giữa các hàng đó.
Các kỹ thuật cơ bản ở đây có thể được điều chỉnh cho phù hợp với bất kỳ yêu cầu thay đổi nào. Điều quan trọng là xây dựng và kiểm tra các truy vấn phụ khi bạn thực hiện.
Không có SQL nào ở gần DBMS; có thể có lỗi trong đó.
Bạn chưa chỉ định DBMS nào bạn đang sử dụng. Tuy nhiên, có vẻ như Oracle sẽ không thích ký hiệu AS được sử dụng cho bí danh bảng, mặc dù nó không có vấn đề gì với AS trên bí danh cột. Nếu bạn đang sử dụng bất kỳ DBMS nào khác, bạn không cần phải lo lắng về độ lệch tâm nhỏ đó.