按日期和类型混合排序

时间:2017-09-18 13:20:48

标签: sql ruby-on-rails postgresql

所以,让我们说我有一个看起来像这样的数据库

Posts
id | author_id | created_at
 1           1    1.day.ago
 2           1    2.day.ago
 3           2    3.day.ago
 4           1    4.day.ago

Authors
id | type
 1   Male
 2   Female

我想对这些帖子进行查询,以便它们以创建的desc顺序返回,但也会遍历所有类型。

所以,如果我刚刚做了:

Post.order('created_at desc')

我会得到:

Posts
id | author_id | created_at
 1           1    1.day.ago
 2           1    2.day.ago
 3           2    3.day.ago
 4           1    4.day.ago

但是,让我们说,我希望结果按此顺序排列:

Posts
id | author_id | created_at
 1           1    1.day.ago
 3           2    3.day.ago
 2           1    2.day.ago
 4           1    4.day.ago

因此,我首先获得作者1的最新帖子,然后是作者2的最新帖子,即使它比作者1的下一篇文章更早,那么,因为没有更多帖子来自作者1作者2,它以正常的created_at顺序返回其余部分。

我们假设大约不会有超过20位作者,但我总是想要浏览彼此最近的帖子,然后是每个帖子的最新帖子,等等。

这可以在sql中执行吗?

3 个答案:

答案 0 :(得分:1)

您可以使用以下内容订购自定义订单:

ORDER BY ROW_NUMBER()OVER(PARTITION BY author_id ORDER BY created_at DESC)
,        author_id

如果将其添加到选择中,您可以更轻松地查看结果,并在必要时应用调整。

至少,在sql server中允许这样做,我同样假设为postgreSQL。

答案 1 :(得分:1)

如果我正确理解,一种方法是:

with Posts(id , author_id , created_at) as(
select 1       ,    1    ,'2017-09-17'::date union all
select 2       ,    1    ,'2017-09-16'::date union all
select 3       ,    2    ,'2017-09-15'::date union all
select 5       ,    2    ,'2017-09-10'::date union all
select 4       ,    1    ,'2017-09-14'::date  
)

select * from (
    select * ,row_number() over(partition by author_id order by created_at desc) as rn  
    from Posts
) t
order by rn, created_at desc

答案 2 :(得分:1)

我们可以在作者的分区上分配行号,并为最新的帖子分配最低的行号。然后按此行号排序,然后是作者ID以打破平局。

select
    t.id,
    t.author_id,
    t.created_at
from
(
    select id, author_id, created_at,
        row_number() over (partition by author_id order by created_at desc) rn
    from Posts
) t
order by
    t.rn,
    t.author_id