Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

ordem sql complexa por


Acho que "id de resposta" é 0 para artigos e é o número do artigo para comentários. Se esse é o seu design, isso deve funcionar:
select * from yourTable
order by
  case when "reply id" = 0 then id else "reply id" end, id

ADICIONADO: Obrigado pelas informações adicionais em seu comentário. Colocar os resultados na ordem que você deseja não é tão fácil, porque a primeira chave de ordenação é a created_date da postagem do início do thread. Isso não está na linha de dados, então você precisa de uma junção. Aqui está meu melhor palpite com base nas informações adicionais (que ainda não estão completas o suficiente para me impedir de adivinhar):
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;

Você pode precisar ajustar a sintaxe para postgre. Eu testei isso no SQL Server.

Se isso ainda não fizer o que você deseja, seja específico sobre como deseja os dados de volta. De preferência, diga-me a ordem "id" que devo ver para os dados em seu arquivo de despejo e também explicar a base para essa ordem. Aqui está o que eu fiz:

  1. Todas as mensagens em um thread (thread =a messages e seus comentários) devem ser agrupadas.

  2. Dentro de um tópico, coloque a mensagem no topo, seguida de seus comentários em ordem cronológica inversa. O thread com o created/_date mais recente deve ser o primeiro, depois o thread com o segundo created_date mais recente e assim por diante. (Seus dados de amostra tinham muitos comentários com a mesma data_de_criação, então usei "id" como uma chave de ordem secundária para os comentários em um encadeamento.)

Observação: Seu dump indica que created_date é atualizado para CURRENT_TIMESTAMP se uma postagem for modificada. Se este for um quadro de mensagens ao vivo, esteja ciente de que isso pode fazer com que os comentários sejam datados antes a mensagem pai, e isso significa que um tópico permanecerá no topo se for modificado com frequência (mesmo sem nenhuma alteração real em seu texto). (Isso não é relevante para a minha solução, mas achei que valia a pena notar.)

Como uma junção é necessária, essa consulta agora será muito mais lenta. Minha sugestão:mantenha duas colunas de data, "thread_last_modified" e "item_last_modified". Você terá que cascatear atualizações de iniciadores de threads para comentários, mas acho que vale a pena se não houver muitas atualizações, porque a consulta pode ser muito mais simples. Eu não testei isso porque requer várias alterações no seu design:
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;

ADICIONADO Nº 2 :Se você quiser apenas o thread contendo o comentário com id ::thisOne, acho que você pode adicionar esta linha entre as cláusulas ON e ORDER BY (para minha primeira solução adicionada, a junção):
where parentfeed.id = (
  select coalesce(reply_id,id)
  from feed
  where id = ::thisOne
)

Em teoria, essa pesquisa deve ser avaliada apenas uma vez para a consulta, mas se não for na prática, você pode pré-computar como ::thisOneThreadID e adicionar
where parentfeed.id = ::thisOneThreadID

Para a segunda solução, supondo que você pré-compute novamente, tente
where coalesce(id,reply_id) = ::thisOneThreadID

A propósito, suspeito que ambas as minhas soluções mesclarão os tópicos que foram modificados pela última vez exatamente ao mesmo tempo ...