Полагаю, что "идентификатор ответа" равен 0 для статей и является номером статьи для комментариев. Если это ваш дизайн, это должно работать:
select * from yourTable
order by
case when "reply id" = 0 then id else "reply id" end, id
ДОБАВЛЕНО: Спасибо за дополнительную информацию в вашем комментарии. Расставить результаты в нужном вам порядке не так-то просто, потому что первый ключ упорядочения - это create_date сообщения начального потока. Это не в строке данных, поэтому вам нужно объединение. Вот мое лучшее предположение, основанное на дополнительной информации (которая все еще не является полной, чтобы не дать мне угадать):
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;
Возможно, вам придется настроить синтаксис для postgre. Я проверил это в SQL Server.
Если это все еще не дает того, что вы хотите, пожалуйста, уточните, как вы хотите вернуть данные. Предпочтительно, сообщите мне порядок «id», который я должен увидеть для данных в вашем файле дампа, и также объяснит основание для этого порядка. Вот что я сделал:
Все сообщения в цепочке (ветка = сообщения и их комментарии) должны быть сгруппированы вместе.
В цепочке поместите сообщение сверху, а затем комментарии в обратном хронологическом порядке. Сначала следует поток с самым последним созданным / _date, затем поток со вторым самым последним созданным_date и т. Д. (В ваших образцах данных было много комментариев с одной и той же созданной датой, поэтому я использовал «id» в качестве вторичного ключа заказа для комментариев в потоке.)
Примечание: Ваш дамп указывает, что create_date обновляется до CURRENT_TIMESTAMP, если сообщение изменено. Если это живая доска объявлений, помните, что это может привести к тому, что комментарии будут датированы до родительского сообщения, и это означает, что поток будет оставаться на вершине, если он часто изменяется (даже без фактического изменения его текст). (Это не относится к моему решению, но я подумал, что это стоит отметить.)
Поскольку требуется соединение, этот запрос теперь будет выполняться намного медленнее. Мое предложение: сохранить два столбца даты, "thread_last_modified" и "item_last_modified". Вам нужно будет каскадно обновлять обновления от потоков до комментариев, но я думаю, что это стоит того, чтобы обновлений было немного, потому что запрос может быть намного проще. Я не проверял это, потому что это требует нескольких изменений в вашем дизайне:
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;
ADDED # 2 : Если вы хотите только поток, содержащий комментарий с id :: thisOne, я думаю, вы можете добавить эту строку между предложениями ON и ORDER BY (для моего первого добавленного решения, присоединиться):
where parentfeed.id = (
select coalesce(reply_id,id)
from feed
where id = ::thisOne
)
Теоретически, этот поиск должен оцениваться только один раз для запроса, но если это не практикуется, вы можете предварительно вычислить его как :: thisOneThreadID и добавить
where parentfeed.id = ::thisOneThreadID
Для второго решения, при условии, что вы выполняете предварительные вычисления снова, попробуйте
where coalesce(id,reply_id) = ::thisOneThreadID
Кстати, я подозреваю, что оба моих решения объединят потоки, которые были изменены в последний раз в одно и то же время ...