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

Získejte aplikace s nejvyšším počtem recenzí od dynamické série dní

Myslím toto je to, co hledáte:

Postgres 13 nebo novější

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 dělá to o něco levnější. Přidáno v Postgres 13 (aktuálně beta). Viz:

Postgres 12 nebo starší

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 zde

Stejné jako výše, ale bez WITH TIES .

Nemusíme zapojovat tabulkové apps vůbec. Tabulka reviews má všechny informace, které potřebujeme.

CTE cte vypočítá nejstarší recenzi a aktuální celkový počet na aplikaci. CTE se vyhýbá opakovaným výpočtům. Mělo by to docela pomoci.
Vždy se zhmotní před Postgres 12 a mělo by se zhmotnit automaticky v Postgresu 12, protože se v hlavním dotazu používá mnohokrát. Jinak můžete přidat klíčové slovo MATERIALIZED v Postgres 12 nebo novější, aby to vynutilo. Viz:

Optimalizovaný generate_series() call vytváří řadu dní od nejstarší po nejnovější recenzi. Viz:

Nakonec LEFT JOIN LATERAL už jsi objevil. Ale protože více aplikací může souviset pro nejvíce recenzí načtěte všechny vítěze, což může být 0 - n aplikací. Dotaz agreguje všechny denní vítěze do pole, takže dostaneme jeden řádek výsledku na review_window_start . Případně definujte nerozhodný výsledek, abyste získali maximálně jeden vítěz. Viz:



  1. Jaká je alternativa klauzule LIMIT v JPQL?

  2. Odesílání hesel přes web

  3. Jak vrátit řetězec v obráceném pořadí pomocí SQL Server – REVERSE()

  4. Po odeslání zachovat hodnoty pole