Postgresql:按数字键值

时间:2018-04-09 15:59:13

标签: json postgresql sql-order-by

我一直在阅读类似的问题,看起来有足够简单的解决方案,但在这里应用它们似乎并不适合我。 我在postgres数据库表中有一个json列,其中包含x和y坐标。在此列上执行简单选择会返回以下内容,例如:

[
{
 "x": "-1.6827080672804147",
 "y": "-0.011726425465745486"
},
{
 "x": "2.4016256261667235",
 "y": "0.016304356672382222"
},
{
 "x": "0.2278035109735127",
 "y": "0.0013854154958112177"
},
{
 "x": "1.2104642489702613",
 "y": "0.008129416140682903"
},
{
 "x": "-0.3281865438803838",
 "y": "-0.0024303442506510738"
},
{
 "x": "-0.2401461868455415",
 "y": "-0.0018261232803209514"
}, 
               .
               .
               .
               .
]

我想按x坐标递增的方式返回此对象。上面的结果集实际上是运行以下查询的结果:

  SELECT coordinates 
    FROM schema_name.table_name
   WHERE ....
     AND ....
ORDER BY coordinates ->> 'x' asc;

我也尝试过使用

ORDER BY cast(coordinates->>'x' as numeric)  ASC

产生以下结果:

ERROR:  cannot cast type json to numeric

我确定这是愚蠢的,我不知道。任何指向正确方向的人都会非常感激。

2 个答案:

答案 0 :(得分:1)

没有必要使问题复杂化,您可以在order by中使用json_agg():

create or replace function sort_my_array(json)
returns json language sql as $$
    select json_agg(value order by (value->>'x')::numeric)
    from json_array_elements($1)
$$

DbFiddle.

答案 1 :(得分:0)

由于所有这些元素都在一个字段中,通过对它进行排序,您正在转换数据,因此您需要将其拆分,订购,然后将其重新组合在一起。

SELECT ('[' || STRING_AGG(j::TEXT, ',' ORDER BY (j->>'x')::NUMERIC) || ']')::JSON
FROM json_array_elements(
'[
{"x": "2.4016256261667235","y": "0.016304356672382222"},
{"x": "-1.6827080672804147","y": "-0.011726425465745486"},
{"x": "0.2278035109735127","y": "0.0013854154958112177"}
]'::JSON) j

结果:

  

[{ “×”: “-1.6827080672804147”, “Y”: “-0.011726425465745486”},{ “×”: “0.2278035109735127”, “Y”: “0.0013854154958112177”},{ “×”: “2.4016256261667235” ,“y”:“0.016304356672382222”}]

我应该注意,我在PG的后续版本中认为可能有比STRING_AGG更好的构造JSON对象的方法,但我使用的是PG 9.3,所以......