sql >> Database >  >> RDS >> PostgreSQL

SQL:hoe selecteer je de rij met de meeste bekende waarden?

Het zal pijnlijk zijn; erg pijnlijk.

Uw vraag is niet duidelijk over dit probleem, maar ik ga ervan uit dat de 'gebruikers-ID' waarnaar u verwijst de gebruikersnaam is. Er zijn consequente wijzigingen die moeten worden aangebracht als dat verkeerd is.

Zoals bij elke complexe vraag, bouw deze in fasen op.

Fase 1:Hoeveel niet-null-velden zijn er 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:Wat is het maximale aantal velden voor een bepaalde gebruikersnaam?

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

Stap 3:Selecteer (alle) rijen voor een bepaalde gebruiker met dat maximale aantal niet-null-velden:

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;

Als iemand nu meerdere rijen heeft met (zeg) alle drie de velden ingevuld, dan worden al die rijen geretourneerd. U heeft echter geen criteria opgegeven om tussen die rijen te kiezen.

De basistechnieken kunnen hier worden aangepast aan eventuele gewijzigde eisen. De sleutel is om de subquery's te bouwen en te testen terwijl je bezig bent.

Geen van deze SQL is in de buurt van een DBMS geweest; er kunnen bugs in zitten.

U hebt niet opgegeven welk DBMS u gebruikt. Het lijkt er echter op dat Oracle de AS-notatie die wordt gebruikt voor tabelaliassen niet zal waarderen, hoewel het geen probleem heeft met AS op kolomaliassen. Als u een ander DBMS gebruikt, hoeft u zich geen zorgen te maken over die kleine excentriciteit.



  1. MySQL vs PostgreSQL JSON zoekfuncties

  2. DictCursor lijkt niet te werken onder psycopg2

  3. Android SQLite LIKE escape-jokerteken

  4. Hoe maak je een SQL-zoekopdracht krachtiger?