sql >> Databasteknik >  >> RDS >> PostgreSQL

SQL:hur väljer man raden med de mest kända värdena?

Det kommer att vara smärtsamt; mycket smärtsamt.

Din fråga är inte tydlig om det här problemet, men jag antar att "användar-id" du hänvisar till är användarnamnet. Det finns följdändringar att göra om det är fel.

Som med alla komplexa frågor, bygg upp den i etapper.

Steg 1:Hur många icke-nullfält finns det per post?

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

Steg 2:Vilket är det maximala antalet sådana fält för ett givet användarnamn?

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

Steg 3:Välj (alla) raderna för en given användare med det maximala antalet icke-nullfält:

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;

Nu, om någon har flera rader med (säg) alla tre fälten ifyllda, kommer alla dessa rader att returneras. Du har dock inte angett några kriterier för att välja mellan dessa rader.

Grundteknikerna här kan anpassas till eventuella ändrade krav. Nyckeln är att bygga och testa underfrågorna allt eftersom.

Inget av denna SQL har varit i närheten av ett DBMS; det kan finnas buggar i den.

Du har inte angett vilken DBMS du använder. Det verkar dock som om Oracle inte kommer att gilla AS-notationen som används för tabellalias, även om det inte har några problem med AS på kolumnalias. Om du använder någon annan DBMS, bör du inte behöva oroa dig för den smärre excentriciteten.



  1. spara python objekt i postgres bord med pickle

  2. T-SQL XOR-operatör

  3. Exempelscheman på GitHub

  4. Mysql CASE HITTER INTE för CASE STATEMENT på en lagrad procedur