PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Pesan dengan hubungan has_many

Kueri dapat berfungsi seperti ini:

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;

Pertama , ambil value "terbaru" untuk name = 'score' per artikel di subkueri m . Penjelasan lebih lanjut untuk teknik yang digunakan dalam jawaban terkait ini:

Anda tampaknya menjadi korban kesalahpahaman yang sangat mendasar:

tidak ada "tatanan alam" dalam sebuah tabel. Dalam SELECT , Anda perlu ORDER BY kriteria yang ditentukan dengan baik. Untuk tujuan kueri ini, saya mengasumsikan kolom metrics.date_created . Jika Anda tidak memiliki hal semacam itu, Anda tidak mungkin untuk mendefinisikan "paling baru" dan dipaksa kembali ke pilihan arbitrer dari beberapa baris kualifikasi:

   ORDER  BY article_id

Ini bukan dapat diandalkan. Postgres akan memilih baris seperti yang dipilihnya. Dapat berubah dengan pembaruan apa pun pada tabel atau perubahan apa pun dalam rencana kueri.

Berikutnya , LEFT JOIN ke tabel article dan ORDER BY value . NULL diurutkan terakhir, jadi artikel tanpa nilai kualifikasi menjadi yang terakhir.

Catatan:beberapa ORM yang tidak terlalu pintar (dan saya khawatir ActiveRecord Ruby adalah salah satunya) menggunakan id yang tidak deskriptif dan tidak khas sebagai nama untuk kunci utama. Anda harus menyesuaikan dengan nama kolom yang sebenarnya, yang tidak Anda berikan.

Kinerja

Harus layak. Ini adalah kueri "sederhana" sejauh menyangkut Postgres. Indeks multikolom parsial pada tabel metrics akan membuatnya lebih cepat:

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

Kolom dalam urutan ini. Di PostgreSQL 9.2+ Anda dapat menambahkan nilai kolom untuk memungkinkan pemindaian hanya indeks:

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kesalahan saat menjalankan migrasi:sqlalchemy.exc.CompileError:Jenis ENUM Postgresql memerlukan nama

  2. Kesalahan saat menggunakan R untuk mendapatkan kredensial dari Windows Cred Vault

  3. Array TypeORM tidak didukung di postgres?

  4. Penyatuan Koneksi PostgreSQL:Bagian 2 – PgBouncer

  5. Hapus menggunakan gabungan luar kiri di Postgres