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

Aplikace Rails 3 s PostgreSQL - Získání seznamu zpráv seskupených podle konverzace

Pokud vám nevadí zašpinit si ruce trochou SQL, můžete použít funkce okna dokončit práci. ID příspěvků můžete získat pomocí tohoto SQL:

select id
from (
    select id,
           rank() over (partition by thread_id order by created_at desc)
    from posts
    where receiver_id = #{user.id}
) as dt
where rank = 1

Pokud chcete více sloupců, přidejte je do obou klauzulí SELECT. #{user.id} je samozřejmě příjemce, který vás zajímá.

Zajímavou částí je funkce okna:

rank() over (partition by thread_id order by created_at desc)

Tím se tabulka rozdělí do skupin na základě thread_id (něco jako lokalizované GROUP BY), seřaďte je podle časového razítka (nejnovější první) a poté rank() dává 1 pro první položku v každé skupině, 2 pro druhou atd.

Vzhledem k tabulce, která vypadá takto:

=> select * from posts;
 id | receiver_id | thread_id |     created_at      
----+-------------+-----------+---------------------
  1 |           1 |         2 | 2011-01-01 00:00:00
  2 |           1 |         2 | 2011-02-01 00:00:00
  3 |           1 |         2 | 2011-03-01 00:00:00
  4 |           1 |         3 | 2011-01-01 00:00:00
  5 |           1 |         4 | 2011-01-01 00:00:00
  6 |           1 |         3 | 2011-01-01 13:00:00
  7 |           2 |        11 | 2011-06-06 11:23:42
(7 rows)

Vnitřní dotaz vám dá toto:

=> select id, rank() over (partition by thread_id order by created_at desc)
   from posts
   where receiver_id = 1;

 id | rank 
----+------
  3 |    1
  2 |    2
  1 |    3
  6 |    1
  4 |    2
  5 |    1
(6 rows)

A pak kolem toho zabalíme vnější dotaz, abychom odstranili pouze shody nejvyššího hodnocení:

=> select id
    from (                                                                  
        select id,
               rank() over (partition by thread_id order by created_at desc)
        from posts
        where receiver_id = 1
    ) as dt
    where rank = 1;

 id 
----
  3
  6
  5
(3 rows)

Přidejte tedy další požadované sloupce a vše zabalte do Post.find_by_sql a máte hotovo.




  1. Dva duplicitní indexy se stejnými sloupci

  2. Je možné použít více/vnořených příkazů MySQLi?

  3. Potenciální vylepšení ASPState

  4. odstranit konkrétní slovo z řetězce