您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

复杂的SQL顺序

复杂的SQL顺序

我猜文章的“回复ID”为0,评论文章号为。如果这是您的设计,这应该可以工作:

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

感谢您在评论中提供其他信息。将结果按所需顺序排列并非易事,因为第一个排序键是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;

您可能需要调整postgre的语法。我在sql Server中对此进行了测试。

如果仍然不能满足您的要求,请具体说明如何恢复数据。最好,告诉我“ID”为了我应该看到在你的转储文件的数据, 说明该订单的基础。这是我所做的:

线程中的所有消息(线程=一条消息及其注释)都应分组在一起。

一个线程中,将消息放在顶部,然后按相反的时间顺序排列其注释。具有最新创建/日期的线程应该位于第一个,然后具有第二创建日期最新的线程,依此类推。(您的样本数据有许多具有相同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;

:如果只希望包含ID为:: thisOne的注释的线程,我认为您可以在ON和ORDER BY子句之间添加此行(对于我的第一个添加解决方案,是join):

where parentFeed.id = (
  select coalesce(reply_id,id)
  from Feed
  where id = ::thisOne
)

从理论上讲,该查询只应对查询进行一次评估,但如果实际中不可行,则可以将其预先计算为:: thisOneThreadID并添加

where parentFeed.id = ::thisOneThreadID

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

where coalesce(id,reply_id) = ::thisOneThreadID

顺便说一句,我怀疑我的两个解决方案都将在同一时间合并上次修改的线程…

SQLServer 2022/1/1 18:36:53 有494人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶