sql >> Databáze >  >> RDS >> PostgreSQL

SQL:jak vybrat řádek s nejznámějšími hodnotami?

Bude to bolestivé; velmi bolestivé.

Vaše otázka není o tomto problému jasná, ale předpokládám, že 'id uživatele', na které odkazujete, je uživatelské jméno. Pokud je to špatně, je třeba provést následné úpravy.

Stejně jako u každého složitého dotazu jej sestavujte po etapách.

Fáze 1:Kolik nenulových polí je v záznamu?

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

Fáze 2:Jaký je maximální počet takových polí pro dané uživatelské jméno?

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

Fáze 3:Vyberte (všechny) řádky pro daného uživatele s tímto maximálním počtem nenulových polí:

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;

Nyní, pokud má někdo více řádků s (řekněme) vyplněnými všemi třemi poli, budou vráceny všechny tyto řádky. Nezadali jste však žádná kritéria, podle kterých byste mezi těmito řádky měli vybírat.

Základní techniky zde mohou být přizpůsobeny jakýmkoli změněným požadavkům. Klíčem je vytvářet a testovat dílčí dotazy za pochodu.

Žádný z těchto SQL nebyl blízko DBMS; mohou v něm být chyby.

Neuvedli jste, který DBMS používáte. Zdá se však, že Oracle nebude mít rád AS notaci používanou pro aliasy tabulek, i když s AS na aliasech sloupců problém nemá. Pokud používáte jakýkoli jiný DBMS, neměli byste si dělat starosti s touto drobnou excentricitou.



  1. Jak zabránit vytvoření primárního klíče UUID pro nové objekty SQLAlchemy se stejnou hodnotou

  2. jQuery ajax neomezený dynamický výběrový box založený na nadřazených kategoriích

  3. Použití dvou agregovaných hodnot z poddotazu SELECT v jednom vnějším dotazu SELECT

  4. Embedded MySQL Server C# Wrapper?