PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Ứng dụng Rails 3 với PostgreSQL - Lấy danh sách các tin nhắn được nhóm theo hội tụ

Nếu bạn không ngại làm bẩn tay với một chút SQL, bạn có thể sử dụng chức năng cửa sổ để hoàn thành công việc. Bạn có thể lấy ID bài đăng bằng SQL này:

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

Nếu bạn muốn nhiều cột hơn, hãy thêm chúng vào cả hai mệnh đề CHỌN. #{user.id} tất nhiên là người nhận mà bạn quan tâm.

Phần thú vị là chức năng cửa sổ:

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

Thao tác này sẽ phân vùng bảng thành các nhóm dựa trên thread_id (loại GROUP BY được bản địa hóa), sắp xếp chúng theo dấu thời gian (gần đây nhất trước), rồi đến rank() mang lại 1 cho mục nhập đầu tiên trong mỗi nhóm, 2 cho mục thứ hai, v.v.

Cho một bảng giống như sau:

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

Truy vấn bên trong cung cấp cho bạn điều này:

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

Và sau đó, chúng tôi bao bọc truy vấn bên ngoài xung quanh điều đó để chỉ loại bỏ các kết quả phù hợp xếp hạng hàng đầu:

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

Vì vậy, hãy thêm các cột bổ sung bạn muốn và gói gọn tất cả trong Post.find_by_sql và bạn đã hoàn tất.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Django - Quan hệ họ hàng không tồn tại. Không thể chạy python management.py di chuyển?

  2. Yii Framework:Không thể tìm thấy bảng cho lớp bản ghi đang hoạt động trong cơ sở dữ liệu

  3. Chọn hàng ngẫu nhiên

  4. Máy chủ PostgreSQL sẽ không tắt trên Lion (Mac OS 10.7)

  5. Hoạt động CASCADE có điều kiện cho ràng buộc khóa ngoại?