PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Приложение Rails 3 с PostgreSQL - Получаване на списък със съобщения, групирани по преобразуване

Ако нямате нищо против да си изцапате ръцете с малко SQL, можете да използвате прозоречна функция за да се свърши работата. Можете да получите идентификаторите на публикацията с този 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

Ако искате повече колони, добавете ги към двете клаузи SELECT. #{user.id} е, разбира се, получателят, от когото се интересувате.

Интересната част е функцията прозорец:

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

Това ще раздели таблицата на групи въз основа на thread_id (нещо като локализирано ГРУПИРАНЕ ПО), подредете ги по клеймото за време (първо най-новите) и след това rank() дава 1 за първия запис във всяка група, 2 за втория и т.н.

Дадена е таблица, която изглежда така:

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

Вътрешната заявка ви дава следното:

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

И след това обгръщаме външната заявка около това, за да отделим само най-високо класираните съвпадения:

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

Така че добавете допълнителните колони, които искате, и увийте всичко в Post.find_by_sql и сте готови.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Архивиране на дизайна на PostgreSQL база данни - без данни

  2. Обработка на страниране с промяна на реда на сортиране

  3. Може ли все още да се чете от заключен ред [в Postgres]?

  4. Предотвратяване на SQL инжектиране в имена на динамични колони

  5. Heroku Postgres DB по-бавен след надграждане