PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Aplikasi Rails 3 dengan PostgreSQL - Mendapatkan daftar pesan yang dikelompokkan berdasarkan percakapan

Jika Anda tidak keberatan mengotori tangan Anda dengan sedikit SQL, Anda dapat menggunakan fungsi jendela untuk menyelesaikan pekerjaan. Anda bisa mendapatkan ID posting dengan SQL ini:

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

Jika Anda ingin lebih banyak kolom, tambahkan ke kedua klausa SELECT. #{user.id} tentu saja adalah penerima yang Anda minati.

Yang menarik adalah fungsi jendelanya:

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

Ini akan mempartisi tabel menjadi beberapa grup berdasarkan thread_id (semacam GROUP BY yang dilokalkan), urutkan berdasarkan stempel waktu (terbaru lebih dulu), lalu rank() menghasilkan 1 untuk entri pertama di setiap grup, 2 untuk entri kedua, dst.

Diberikan tabel yang terlihat seperti ini:

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

Permintaan batin memberi Anda ini:

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

Dan kemudian kami membungkus kueri luar itu untuk mengupas hanya kecocokan peringkat teratas:

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

Jadi tambahkan kolom tambahan yang Anda inginkan dan bungkus semuanya dalam Post.find_by_sql dan selesai.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tampilkan semua nama database

  2. Kueri bersarang dalam squeel

  3. Nama tabel atau kolom tidak boleh diawali dengan angka?

  4. Bagaimana cara menerapkan pagination ke hasil kueri SQL dengan Gabung?

  5. Penyimpanan zona waktu dalam stempel waktu tipe data dengan zona waktu