PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

SQL:làm thế nào để chọn hàng có nhiều giá trị nhất?

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ỏ đó.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Truy vấn PostgreSQL để liệt kê tất cả các tên bảng?

  2. Ghi vào tệp từ RAISE NOTICE trong postgresql

  3. Số tiền kiểm tra kích hoạt Postgres trước khi xóa

  4. Tìm hiểu về kích thước hàng Postgres

  5. Đối số dòng lệnh PSQL trong tập lệnh DO