【问题标题】:Order by the IN value with jsonb array使用 jsonb 数组按 IN 值排序
【发布时间】:2017-10-30 01:55:03
【问题描述】:

我正在尝试根据另一行的数组元素的顺序选择记录:

SELECT * 
  FROM tester
  WHERE id IN (
    SELECT jsonb_array_elements(d->'fam')->>'id' 
    FROM tester
    WHERE id='3'
  ) 

我知道this solution

不同之处在于我不知道如何动态生成“排序”值。这可能吗?

完整的fiddle is here

我想根据 json 数据中的顺序查看结果:

id  name    d
--  -----   --------
2   barb    {"fam": [{"id": 1}, {"id": 3}]}
4   jaimie  {"fam": [{"id": 3}, {"id": 2}, {"id": 1}]}
1   bob     {"fam": [{"id": 3}, {"id": 2}, {"id": 4}]}

【问题讨论】:

  • 什么应该在您的预期结果集中生成排序?您演示中的 JSON 数据似乎已经具有您想要的顺序。
  • 是,但返回的行顺序不同

标签: sql arrays postgresql jsonb set-returning-functions


【解决方案1】:

LATERAL 连接中使用WITH ORDINALITY 以保留数组的原始顺序:

SELECT t.* 
FROM   tester t1
CROSS  JOIN jsonb_array_elements(t1.d->'fam') WITH ORDINALITY fam(id, ord)
JOIN   tester t ON t.id = fam.id->>'id'
WHERE  t1.id = '3'
ORDER  BY fam.ord;

SQL Fiddle.

注意一个细微的区别:原始查询中的IN 构造不仅删除了原始顺序,还删除了重复项。我的查询以原始顺序保留从数组中提取的所有 ID,无论是否重复。

LATERAL 关键字是table functions 的可选噪声。 table 别名的 AS 关键字也是如此。会去这里:

CROSS  JOIN <b>LATERAL</b> jsonb_array_elements(d-&gt;'fam') WITH ORDINALITY <b>AS</b> fam(id, ord)

相关:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-10
    • 1970-01-01
    相关资源
    最近更新 更多