Posgres:按:: timestamp排序和jsonb列的desc给出相同的结果,如何按上一个时间戳排序

时间:2018-11-11 13:31:30

标签: postgresql postgresql-9.1 postgresql-9.4

我有此查询,该查询根据表文档的UUID doc_id检索1行,该查询还具有字段列类型jsonb:

select 
    DISTINCT ON (doc_id) 
    *
    FROM ( 
        select d.doc_id, c.comments 
        from documents as d 
        cross join lateral jsonb_array_elements(comments) 
        WITH ORDINALITY c(comments)
        WHERE (c.comments ->> 'isUser'):: boolean is false 
        order by (c.comments ->>'timestamp')::timestamp desc
    ) as s;

当我尝试:

        order by (c.comments ->>'timestamp')::timestamp desc

我得到完全相同的结果。我什至尝试使用timestamptz

        order by (c.comments ->>'timestamp')::timestamptz asc

jsonb注释列的示例内容:

[...
{
    "text": "30",
    "timestamp": "2018-11-11T09:13:23.242Z", // older
    "isUser": false
},{
    "text": "31",
    "timestamp": "2018-11-11T12:53:48.620Z", // LATEST
    "isUser": false
}]

您会看到文本30的对象较旧,但始终会在上面的查询中返回。

1 个答案:

答案 0 :(得分:1)

该顺序与最终结果无关,因为该顺序仅适用于使用它的SELECT语句,即您的子查询。然后,您使用DISTINCT ON对这些结果执行另一个查询,该查询将执行任何计算并以 some 的顺序返回结果,但可能不是您想要的结果。

要允许您在外部查询中进行排序,必须在该级别上访问要在订单中使用的字段。这意味着子查询还必须返回timestamp字段,然后外部查询可以对此进行排序,但不能选择它(以使返回的列保持相同)。

select 
    DISTINCT ON (doc_id) 
    doc_id, comments
    FROM ( 
        select d.doc_id, c.comments, (c.comments ->>'timestamp')::timestamp AS comment_timestamp
        from documents as d 
        cross join lateral jsonb_array_elements(comments) 
        WITH ORDINALITY c(comments)
        WHERE (c.comments ->> 'isUser'):: boolean is false 
    ) as s
ORDER BY doc_id, comment_timestamp DESC

我可能遗漏了一些东西,但看来您还是不需要子查询,这行不通吗?

select DISTINCT ON (d.doc_id) d.doc_id, c.comments 
from documents as d 
cross join lateral jsonb_array_elements(comments) 
WITH ORDINALITY c(comments)
WHERE (c.comments ->> 'isUser'):: boolean is false 
order by d.doc_id, (c.comments ->>'timestamp')::timestamp desc