【问题标题】:Select columns and in a jsonb column only return the last element where meets condition选择列并在 jsonb 列中仅返回满足条件的最后一个元素
【发布时间】:2018-11-11 20:52:25
【问题描述】:

我有表 documents,我想选择列 foo 和 bar。还有commentsjsonb

但在comments 中,我只需要满足条件"isUser":false 的最后一个元素。

"select foo, bar, comments from documents 
 where comments @> '[{"isUser":false}]' 
 limit 1 " /*just limit by 1, the latest comment where isUser = false*/

这就是comments 列中 json 的样子:

[{
    "text": "1 sample lorem ipsum",
    "authorId": "0dcd5a36-2778-4fc4-bbc1-112ed61f1362",
    "timestamp": "2018-11-11T08:46:39.608Z",
    "isUser": false
},{
    "text": "2 sample lorem",
    "authorId": "0dcd5a36-2778-4fc4-bbc1-112ed61f1362",
    "timestamp": "2018-11-11T08:46:41.237Z",
    "isUser": true
},{
...]

对于comments,我只需要"isUser":false所在的最后一个对象

【问题讨论】:

  • 向我们展示 json 的实际外观以及您希望从中看到的输出的一些示例。

标签: postgresql postgresql-9.5


【解决方案1】:

您可以使用jsonb_array_elements .. WITH ORDINALITY获取订单

select foo, bar, j.comments
from 
  documents cross 
  join lateral jsonb_array_elements(comments) WITH ORDINALITY j(comments, rn)
WHERE 
  (j.comments ->> 'isUser'):: boolean is false
  ORDER BY j.rn DESC LIMIT 1;

编辑

我希望它限制为 cmets 中 jsonarray 内的 1 个 json 对象

select DISTINCT ON ( foo, bar) foo,bar,comments
FROM 
( select d.foo,d.bar,j.comments,j.rn
from 
  documents d cross 
    join lateral jsonb_array_elements(comments) WITH ORDINALITY j(comments, rn)
WHERE 
  (j.comments ->> 'isUser'):: boolean is false
  ) s
  ORDER BY foo,bar,rn desc  ;

Demo

【讨论】:

  • 谢谢,当我在末尾添加 limit 1 但没有得到 json 数组中的最后一个时,有点工作,插入顺序不保证吗?
  • @commonSenseCode : 现在检查。
  • 一些进步,所以我测试了插入更多的值。现在这是限制主行返回(foo,bar,cmets),我希望它限制在comments 中的 jsonarray 内的 1 个 json 对象,而不是限制行。
  • @commonSenseCode :这基本上是每组问题的前 1 名。您可以使用DISTINCT ON。检查了它。请记住,当您提出问题时,您的示例数据和预期输出应反映完整的要求。
  • 嗨 Kaushik,这更接近我所需要的,是否可以通过 cmets 中的字段时间戳来订购 DESC。不知何故,有时它不会给出最后添加的评论
猜你喜欢
  • 2015-07-09
  • 1970-01-01
  • 1970-01-01
  • 2017-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多