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

Dapatkan aplikasi dengan jumlah ulasan tertinggi sejak rangkaian hari yang dinamis

Saya berpikir ini yang kamu cari:

Postgres 13 atau yang lebih baru

WITH cte AS (  -- MATERIALIZED
   SELECT app_id, min(review_date) AS earliest_review, count(*)::int AS total_ct
   FROM   reviews
   GROUP  BY 1
   )
SELECT *
FROM  (
   SELECT generate_series(min(review_date)
                        , max(review_date)
                        , '1 day')::date
   FROM   reviews
   ) d(review_window_start)
LEFT  JOIN LATERAL (
   SELECT total_ct, array_agg(app_id) AS apps
   FROM  (
      SELECT app_id, total_ct
      FROM   cte c
      WHERE  c.earliest_review >= d.review_window_start
      ORDER  BY total_ct DESC
      FETCH  FIRST 1 ROWS WITH TIES  -- new & hot
      ) sub
   GROUP  BY 1
   ) a ON true;

WITH TIES membuatnya sedikit lebih murah. Ditambahkan di Postgres 13 (saat ini beta). Lihat:

Postgres 12 atau lebih lama

WITH cte AS (  -- MATERIALIZED
   SELECT app_id, min(review_date) AS earliest_review, count(*)::int AS total_ct
   FROM   reviews
   GROUP  BY 1
   )
SELECT *
FROM  (
   SELECT generate_series(min(review_date)
                        , max(review_date)
                        , '1 day')::date
   FROM   reviews
   ) d(review_window_start)
LEFT  JOIN LATERAL (
   SELECT total_ct, array_agg(app_id) AS apps
   FROM  (
      SELECT total_ct, app_id
          ,  rank() OVER (ORDER BY total_ct DESC) AS rnk
      FROM   cte c
      WHERE  c.earliest_review >= d.review_window_start
      ) sub
   WHERE  rnk = 1
   GROUP  BY 1
   ) a ON true;

db<>fiddle di sini

Sama seperti di atas, tapi tanpa WITH TIES .

Kami tidak perlu melibatkan tabel apps sama sekali. Tabel reviews memiliki semua informasi yang kami butuhkan.

cte CTE menghitung ulasan paling awal &jumlah total saat ini per aplikasi. CTE menghindari perhitungan berulang. Harus sedikit membantu.
Itu selalu terwujud sebelum Postgres 12, dan harus terwujud secara otomatis di Postgres 12 karena digunakan berkali-kali dalam permintaan utama. Jika tidak, Anda dapat menambahkan kata kunci MATERIALIZED di Postgres 12 atau lebih baru untuk memaksanya. Lihat:

generate_series() yang dioptimalkan panggilan menghasilkan serangkaian hari dari ulasan paling awal hingga terbaru. Lihat:

Terakhir, LEFT JOIN LATERAL Anda sudah menemukan. Namun karena beberapa aplikasi dapat mengikat untuk ulasan terbanyak, ambil semua pemenang, yang dapat berupa 0 - n aplikasi. Kueri menggabungkan semua pemenang harian ke dalam larik, jadi kami mendapatkan satu baris hasil per review_window_start . Atau, tentukan tiebreaker untuk mendapatkan paling banyak satu pemenang. Lihat:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mengapa bahkan menggunakan *DB.exec() atau pernyataan yang disiapkan di Golang?

  2. Django form/database error:nilai terlalu panjang untuk tipe karakter yang bervariasi (4)

  3. Spring Boot REST · @Constraint untuk dihapus?

  4. Masukkan ke dalam tabel setelah mendapatkan ID dari tabel lain

  5. Postgres mengonversi tipe PATH ke ARRAY