sql >> Database >  >> RDS >> PostgreSQL

Rails 3-app met PostgreSQL - De lijst met berichten krijgen gegroepeerd op converstation

Als je het niet erg vindt om je handen vuil te maken met een beetje SQL, kun je een vensterfunctie om de klus te klaren. Je kunt de post-ID's krijgen met deze 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

Als u meer kolommen wilt, voegt u deze toe aan beide SELECT-clausules. De #{user.id} is natuurlijk de ontvanger waarin u geïnteresseerd bent.

Het interessante deel is de vensterfunctie:

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

Dit verdeelt de tabel in groepen op basis van thread_id (soort van een gelokaliseerde GROUP BY), sorteer ze op tijdstempel (meest recente eerst), en dan rank() levert 1 op voor het eerste item in elke groep, 2 voor de tweede, enz.

Gegeven een tabel die er als volgt uitziet:

=> 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)

De innerlijke vraag geeft je dit:

=> 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)

En dan wikkelen we de buitenste vraag daar omheen om alleen de toprangschikkingsovereenkomsten af ​​te pellen:

=> 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)

Dus voeg de extra kolommen toe die je wilt en verpak het allemaal in een Post.find_by_sql en je bent klaar.




  1. Maak een tabel van twee typen in PostgreSQL

  2. Een index maken op een MySQL-kolom op basis van de lengte van de inhoud?

  3. JPA Entiteitsklasse geeft fout met 2 @GeneratedValue-velden

  4. Orakelprocedure