PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

SQL:come selezionare la riga con i valori più conosciuti?

Sarà doloroso; molto doloroso.

La tua domanda non è chiara su questo problema, ma presumo che l'"ID utente" a cui ti riferisci sia il nome utente. Ci sono modifiche consequenziali da apportare in caso di errore.

Come per qualsiasi query complessa, costruiscila in più fasi.

Fase 1:quanti campi non null ci sono per record?

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

Fase 2:qual è il numero massimo di campi per un determinato nome utente?

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

Fase 3:seleziona (tutte) le righe per un determinato utente con quel numero massimo di campi non nulli:

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;

Ora, se qualcuno ha più righe con (diciamo) tutti e tre i campi compilati, tutte quelle righe verranno restituite. Tuttavia, non hai specificato alcun criterio in base al quale scegliere tra queste righe.

Le tecniche di base qui possono essere adattate a qualsiasi esigenza modificata. La chiave è creare e testare le sottoquery mentre procedi.

Nessuno di questi SQL è stato vicino a un DBMS; potrebbero esserci dei bug.

Non hai specificato quale DBMS stai utilizzando. Tuttavia, sembra che a Oracle non piaccia la notazione AS utilizzata per gli alias di tabella, sebbene non abbia problemi con AS sugli alias di colonna. Se stai utilizzando qualsiasi altro DBMS, non dovresti preoccuparti di quella piccola eccentricità.