Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

urutan sql yang rumit oleh

Saya akan menebak bahwa "id balasan" adalah 0 untuk artikel dan merupakan nomor artikel untuk komentar. Jika itu desain Anda, ini akan berhasil:

select * from yourTable
order by
  case when "reply id" = 0 then id else "reply id" end, id

DITAMBAHKAN: Terima kasih atas informasi tambahan dalam komentar Anda. Untuk menempatkan hasil dalam urutan yang Anda inginkan tidak begitu mudah, karena kunci urutan pertama adalah tanggal dibuat dari posting thread-starter. Ini tidak ada di baris data, jadi Anda perlu bergabung. Ini tebakan terbaik saya berdasarkan informasi tambahan (yang masih belum cukup lengkap untuk membuat saya tidak menebak):

select
  f.id, f.user_id, f.type, f.reply_id, f.text, f.url, f.created_date,
  coalesce(parentfeed.created_date,f.created_date) as thread_date
from feed as f left outer join feed as parentfeed
on f.reply_id = parentfeed.id
order by
  thread_date desc,
  case when f.reply_id = 0 then 0 else 1 end,
  created_date desc, id;

Anda mungkin perlu menyesuaikan sintaks untuk postgre. Saya menguji ini di SQL Server.

Jika ini masih tidak melakukan apa yang Anda inginkan, harap spesifikkan tentang bagaimana Anda ingin datanya kembali. Sebaiknya, beri tahu saya urutan "id" yang harus saya lihat untuk data di file dump Anda, dan juga jelaskan dasar dari perintah tersebut. Inilah yang saya lakukan:

  1. Semua pesan dalam utas (utas =pesan dan komentarnya) harus dikelompokkan bersama.

  2. Di dalam utas, letakkan pesan di atas, diikuti dengan komentarnya dalam urutan kronologis terbalik. Utas dengan tanggal dibuat/_ terbaru harus menjadi yang pertama, kemudian utas dengan tanggal_buatan terbaru kedua, dan seterusnya. (Data sampel Anda memiliki banyak komentar dengan tanggal_buatan yang sama, jadi saya menggunakan "id" sebagai kunci urutan sekunder untuk komentar dalam utas.)

Catatan: Dump Anda menunjukkan bahwa create_date diperbarui ke CURRENT_TIMESTAMP jika posting diubah. Jika ini adalah papan pesan langsung, ketahuilah bahwa ini dapat menyebabkan komentar diberi tanggal sebelum pesan induk, dan itu berarti utas akan tetap di atas jika sering diubah (bahkan tanpa perubahan aktual pada teksnya). (Itu tidak relevan dengan solusi saya, tapi saya pikir itu perlu diperhatikan.)

Karena gabungan diperlukan, kueri ini sekarang akan jauh lebih lambat. Saran saya:pertahankan dua kolom tanggal, "thread_last_modified" dan "item_last_modified". Anda harus mengalirkan pembaruan dari pembuka utas ke komentar, tetapi saya pikir itu sepadan jika tidak ada banyak pembaruan, karena kuerinya bisa jauh lebih sederhana. Saya belum menguji ini karena memerlukan beberapa perubahan pada desain Anda:

select
  id, user_id, type, reply_id, text, url, thread_last_modified, item_last_modified
from feed
order by
  thread_last_modified desc,
  case when f.reply_id = 0 then 0 else 1 end,
  item_last_modified desc, id;

DITAMBAH #2 :Jika Anda hanya menginginkan utas yang berisi komentar dengan id ::thisOne, saya pikir Anda dapat menambahkan baris ini di antara klausa ON dan ORDER BY (untuk solusi tambahan pertama saya, gabungkan):

where parentfeed.id = (
  select coalesce(reply_id,id)
  from feed
  where id = ::thisOne
)

Secara teori, pencarian ini harus dievaluasi hanya sekali untuk kueri, tetapi jika tidak dalam praktiknya, Anda dapat menghitungnya terlebih dahulu sebagai ::thisOneThreadID dan menambahkan

where parentfeed.id = ::thisOneThreadID

Untuk solusi kedua, dengan asumsi Anda menghitung ulang lagi, coba

where coalesce(id,reply_id) = ::thisOneThreadID

Omong-omong, saya menduga kedua solusi saya akan menggabungkan utas yang terakhir diubah pada waktu yang sama...



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Batasan kunci asing gagal

  2. Tambahkan data ke data yang ada di Database MySQL

  3. com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:di mysql

  4. Mengembalikan baris 'terakhir' dari setiap 'grup menurut' di MySQL

  5. Dapatkan satu item dari string daftar di MySQL