复杂的sql顺序

Bas*_*sit 6 mysql sql

id    |    message    |    reply id    |    date  

1     |  my new app.. |     0          | 10 / 10 / 2009 (latest message on top, follow by replies)
5     | love ur app.. |     1          | 11 / 10 / 2009 (this should show under the main message)
6     | another comm  |     1          | 12 / 10 / 2009
2     | application 2 |     0          | 09 / 10 / 2009
3     | reply of 2    |     2          | 11 / 10 / 2009
Run Code Online (Sandbox Code Playgroud)

我想在主要评论之后显示最新评论及其回复.显然回复将有最新的日期,所以我不能按日期排序,因为回复将在主要的顶部.我不确定如何使用一个查询正确执行此操作.请问任何想法.

数据库转储:http://pastie.org/576963

Ste*_*ass 8

我猜对于文章,"回复id"为0,是评论的文章编号.如果这是你的设计,这应该工作:

select * from yourTable
order by
  case when "reply id" = 0 then id else "reply id" end, id
Run Code Online (Sandbox Code Playgroud)

补充:感谢您在评论中提供的其他信息.将结果按所需顺序放置并不容易,因为第一个排序键是thread-starter帖子的created_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;
Run Code Online (Sandbox Code Playgroud)

您可能需要调整postgre的语法.我在SQL Server中测试了这个.

如果这仍然没有达到您想要的效果,请具体说明您希望如何恢复数据.最好,告诉我"ID"为了我应该看到在你的转储文件的数据,说明该订单的基础.这是我做的:

  1. 线程中的所有消息(thread =消息及其注释)应该组合在一起.

  2. 在一个帖子中,将消息置于顶部,然后按反向时间顺序将其注释.具有最新创建的/ _date的线程应该是第一个,然后是具有第二个最近的created_date的线程,依此类推.(您的示例数据具有相同created_date的许多注释,因此我使用"id"作为线程中注释的辅助订单键.)

注意:您的转储表明如果修改了帖子,created_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;
Run Code Online (Sandbox Code Playgroud)

ADDED#2:如果你只想要包含带有id :: thisOne的注释的线程,我想你可以在ON和ORDER BY子句之间添加这一行(对于我的第一个添加的解决方案,连接):

where parentfeed.id = (
  select coalesce(reply_id,id)
  from feed
  where id = ::thisOne
)
Run Code Online (Sandbox Code Playgroud)

从理论上讲,这个查询应该只针对查询进行一次评估,但是如果它不在实践中,你可以将它预先计算为:: thisOneThreadID并添加

where parentfeed.id = ::thisOneThreadID
Run Code Online (Sandbox Code Playgroud)

对于第二种解决方案,假设您再次预先计算,请尝试

where coalesce(id,reply_id) = ::thisOneThreadID
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我怀疑我的两个解决方案将合并最后一次修改的线程...