PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

SQL:jak wybrać wiersz z najbardziej znanymi wartościami?

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ść.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Spowodowane przez:org.postgresql.util.PSQLException:FATAL:uwierzytelnianie hasła nie powiodło się dla użytkownika admin

  2. Indeksowanie SQL na varchar

  3. PostgreSQL:zwróć wiadomość po zliczeniu =0

  4. Używanie CASE w PostgreSQL do jednoczesnego wpływania na wiele kolumn

  5. Stawanie się Superużytkownikiem Bazy Danych - Engineyard