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

Objednávka se vztahem has_many

Dotaz by mohl fungovat takto:

SELECT a.*
FROM   article a
LEFT   JOIN (
   SELECT DISTINCT ON (article_id)
          article_id, value
   FROM   metrics m
   WHERE  name = 'score'
   ORDER  BY article_id, date_created DESC
   ) m ON m.metrics_id = a.metrics_id
ORDER  BY m.value DESC;

Za prvé , načtěte "nejnovější" value pro name = 'score' na článek v poddotazu m . Další vysvětlení použité techniky v této související odpovědi:

Zdá se však, že jste se stali obětí velmi základní mylné představy:

Neexistuje žádný "přirozený řád" v tabulce. V SELECT , musíte ORDER BY dobře definovaná kritéria. Pro účely tohoto dotazu předpokládám sloupec metrics.date_created . Pokud nic takového nemáte, nemůžete definovat „nejnovější“ a jsou nuceni vrátit se k libovolnému výběru z více kvalifikačních řádků:

   ORDER  BY article_id

Toto není spolehlivý. Postgres si vybere řádek podle svého. Může se změnit s jakoukoli aktualizací tabulky nebo jakoukoli změnou v plánu dotazů.

Další , LEFT JOIN do tabulky article a ORDER BY value . NULL seřadí jako poslední, takže články bez kvalifikační hodnoty budou poslední.

Poznámka:Některé nepříliš chytré ORM (a obávám se, že Ruby's ActiveRecord je jedním z nich) používají nepopisné a nerozlišující id jako název primárního klíče. Budete se muset přizpůsobit skutečným názvům sloupců, které jste nezadali.

Výkon

Mělo by být slušné. Toto je "jednoduchý" dotaz, pokud jde o Postgres. Částečný vícesloupcový index v tabulce metrics by to zrychlilo:

CREATE INDEX metrics_some_name_idx ON metrics(article_id, date_created)
WHERE name = 'score';

Sloupce v tomto pořadí. V PostgreSQL 9.2+ můžete přidat hodnotu sloupce, aby bylo možné skenovat pouze index:

CREATE INDEX metrics_some_name_idx ON metrics(article_id, date_created, value)
WHERE name = 'score';



  1. Jak provést zvýraznění výsledků z fulltextového dotazu SQL Server

  2. provést cronjob přesně jednou

  3. Získejte verzi PostGIS

  4. Jak z databáze dostat DateTime s možnou hodnotou Null