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

Bestil med et har_mange forhold

Forespørgslen kunne fungere sådan her:

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;

Først , hent den "seneste" value for name = 'score' pr. artikel i underforespørgslen m . Mere forklaring på den anvendte teknik i dette relaterede svar:

Du ser dog ud til at blive offer for en meget grundlæggende misforståelse:

Der er ingen "naturlig orden" i en tabel. I en SELECT , skal du ORDER BY veldefinerede kriterier. Til formålet med denne forespørgsel antager jeg en kolonne metrics.date_created . Hvis du ikke har noget af den slags, har du ingen måde for at definere "seneste" og er tvunget til at falde tilbage til et vilkårligt valg fra flere kvalificerende rækker:

   ORDER  BY article_id

Dette er ikke pålidelig. Postgres vil vælge en række, som den vælger. Kan ændre sig med enhver opdatering af tabellen eller enhver ændring i forespørgselsplanen.

Næste , LEFT JOIN til tabellen article og ORDER BY value . NULL sorterer sidst, så artikler uden kvalificerende værdi kommer sidst.

Bemærk:nogle ikke-så-smarte ORM'er (og jeg er bange for, at Ruby's ActiveRecord er en af ​​dem) bruger det ikke-beskrivende og ikke-særprægede id som navn for den primære nøgle. Du bliver nødt til at tilpasse dig dine faktiske kolonnenavne, som du ikke har angivet.

Ydeevne

Bør være anstændigt. Dette er en "simpel" forespørgsel, hvad Postgres angår. Et delvist indeks med flere kolonner på tabel metrics ville gøre det hurtigere:

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

Kolonner i denne rækkefølge. I PostgreSQL 9.2+ kan du tilføje kolonneværdien for at gøre indeks-scanninger mulige:

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



  1. Hvordan bruger man Memcached med PHP7?

  2. PHP Pass bruger-id til mysql trigger

  3. Hvordan transponeres kolonner og rækker i PostgreSQL (dvs. hvordan skifter jeg rækker og kolonner)?

  4. Oracle Sequence nextval hopper nummer frem og tilbage