PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Aplikacja Rails 3 z PostgreSQL - Pobieranie listy wiadomości pogrupowanych według konwersacji

Jeśli nie masz nic przeciwko ubrudzeniu sobie rąk odrobiną SQL, możesz użyć funkcja okna aby wykonać pracę. Możesz uzyskać identyfikatory postów za pomocą tego kodu 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

Jeśli chcesz więcej kolumn, dodaj je do obu klauzul SELECT. #{user.id} jest oczywiście odbiorcą, którym jesteś zainteresowany.

Interesującą częścią jest funkcja okna:

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

Spowoduje to podzielenie tabeli na grupy na podstawie thread_id (rodzaj zlokalizowanego GROUP BY), uporządkuj je według sygnatury czasowej (najpierw najnowsze), a następnie rank() daje 1 dla pierwszego wpisu w każdej grupie, 2 dla drugiego itd.

Biorąc pod uwagę tabelę, która wygląda tak:

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

Wewnętrzne zapytanie daje to:

=> 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 następnie owijamy zewnętrzne zapytanie wokół tego, aby oddzielić tylko najlepsze dopasowania w rankingu:

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

Dodaj więc dodatkowe kolumny, które chcesz, i zapakuj je w Post.find_by_sql i gotowe.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Brak pozwolenia podczas ustawiania ruby ​​na szynach

  2. Tabela średniej historii akcji

  3. Jak dodać moduł do Wildfly za pomocą CLI

  4. BŁĄD:dodatkowe dane po ostatniej oczekiwanej kolumnie podczas korzystania z PostgreSQL COPY

  5. Nie można połączyć się z serwerem PostgreSQL:nie można połączyć się z serwerem:Odmowa uprawnień