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:
-
Semua pesan dalam utas (utas =pesan dan komentarnya) harus dikelompokkan bersama.
-
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...