Sql 是否有一个函数允许我输出json数组中元素的当前索引?
我有以下示例PostgresSQL查询Sql 是否有一个函数允许我输出json数组中元素的当前索引?,sql,json,postgresql,select,postgresql-9.4,Sql,Json,Postgresql,Select,Postgresql 9.4,我有以下示例PostgresSQL查询 SELECT name, json_array_elements(myjson)->>'id' id FROM (SELECT 'Dingsda'::text AS name, json_build_array('{"id" : 100}'::json, '{"id" : 200}'::json) myjson UNION ALL SELECT 'Dingsbums'::text AS name, json_build_array('{"
SELECT name, json_array_elements(myjson)->>'id' id FROM
(SELECT 'Dingsda'::text AS name, json_build_array('{"id" : 100}'::json, '{"id" : 200}'::json) myjson
UNION ALL
SELECT 'Dingsbums'::text AS name, json_build_array('{"id" : 101}'::json, '{"id" : 201}'::json, '{"id" : 301}'::json) myjson
) t;
它输出下表
+-----------+-----+
|姓名| id|
+-----------+-----+
|丁斯达| 100|
|丁斯达| 200|
|丁斯本斯| 101|
|丁斯本斯| 201|
+-----------+-----+
现在,我试图实现的是在末尾添加第三列,其中包含json数组元素的索引,从0开始,以此类推。结果应该如下所示
+-----------+-----+-------+
|名称| id |索引|
+-----------+-----+-------+
|丁斯达| 100 | 0|
|丁斯达| 200 | 1|
|丁斯本斯| 101 | 0|
|丁斯本斯| 201 | 1|
|丁斯本斯| 301 | 2|
+-----------+-----+-------+
不幸的是,我还没有找到一个可以帮助我的函数。我尝试在上使用row_number(),但当涉及到json
类型化列时,它似乎会返回奇怪的结果
是否有任何功能可以支持这个相当简单的需求
编辑
Mureinik的回答很有帮助,但是我希望能够保留json中元素的原始序列。在本例中,序列丢失。我认为这是不确定的
SELECT name, id, ROW_NUMBER() OVER (PARTITION BY name ORDER BY 1)
FROM (SELECT name, JSON_ARRAY_ELEMENTS(myjson)->>'id' id
FROM (SELECT 'Dingsda'::text AS name, JSON_BUILD_ARRAY('{"id" : 100}'::json, '{"id" : 200}'::json, '{"id" : 300}'::json, '{"id" : 400}'::json) myjson
UNION ALL
SELECT 'Dingsbums'::text AS name, JSON_BUILD_ARRAY('{"id" : 101}'::json, '{"id" : 201}'::json, '{"id" : 301}'::json) myjson
) t
) s;
+-----------+-----+-------+
|名称| id |索引|
+-----------+-----+-------+
|丁斯本斯| 101 | 1|
|丁斯本斯| 201 | 2|
|丁斯本斯| 301 | 3|
|丁斯达| 100 | 1|
|丁斯达| 400 | 2|
|丁斯达| 200 | 3|
|丁斯达| 300 | 4|
+-----------+-----+-------+
使用行数
似乎是正确的方法。您只需将此查询与另一个查询打包即可生成行的编号:
SELECT name, id, ROW_NUMBER() OVER (PARTITION BY name ORDER BY 1)
FROM (SELECT name, JSON_ARRAY_ELEMENTS(myjson)->>'id' id
FROM (SELECT 'Dingsda'::text AS name, JSON_BUILD_ARRAY('{"id" : 100}'::json, '{"id" : 200}'::json) myjson
UNION ALL
SELECT 'Dingsbums'::text AS name, JSON_BUILD_ARRAY('{"id" : 101}'::json, '{"id" : 201}'::json, '{"id" : 301}'::json) myjson
) t
) s;
使用行数
似乎是正确的方法。您只需将此查询与另一个查询打包即可生成行的编号:
SELECT name, id, ROW_NUMBER() OVER (PARTITION BY name ORDER BY 1)
FROM (SELECT name, JSON_ARRAY_ELEMENTS(myjson)->>'id' id
FROM (SELECT 'Dingsda'::text AS name, JSON_BUILD_ARRAY('{"id" : 100}'::json, '{"id" : 200}'::json) myjson
UNION ALL
SELECT 'Dingsbums'::text AS name, JSON_BUILD_ARRAY('{"id" : 101}'::json, '{"id" : 201}'::json, '{"id" : 301}'::json) myjson
) t
) s;
切勿在SELECT
子句中使用设置返回函数(如json\u array\u elements()
),除非您确切知道自己在做什么。这只会让你更难受
您可以使用table functions(9.4+)的子句,它正是为了解决您的问题:
SELECT name, elem->>'id' id, "index"
FROM (SELECT 'Dingsda'::text AS name, json_build_array('{"id" : 100}'::json, '{"id" : 200}'::json) myjson
UNION ALL
SELECT 'Dingsbums'::text AS name, json_build_array('{"id" : 101}'::json, '{"id" : 201}'::json, '{"id" : 301}'::json) myjson) t,
json_array_elements(t.myjson) WITH ORDINALITY e(elem, "index");
您也可以与json_array_length()
一起使用,但将与ORDINALITY
一起使用要简单得多。除非您确切知道自己在做什么,否则不要在SELECT子句中使用设置返回函数(例如json_array_elements()
)。这只会让你更难受
您可以使用table functions(9.4+)的子句,它正是为了解决您的问题:
SELECT name, elem->>'id' id, "index"
FROM (SELECT 'Dingsda'::text AS name, json_build_array('{"id" : 100}'::json, '{"id" : 200}'::json) myjson
UNION ALL
SELECT 'Dingsbums'::text AS name, json_build_array('{"id" : 101}'::json, '{"id" : 201}'::json, '{"id" : 301}'::json) myjson) t,
json_array_elements(t.myjson) WITH ORDINALITY e(elem, "index");
您也可以与json_array_length()
一起使用,但与序数一起使用更简单。您可以使用横向连接(无论如何推荐)和与序数一起使用
SELECT name, x.element ->> 'id' as id, x.idx
FROM (
SELECT 'Dingsda'::text AS name, json_build_array('{"id" : 100}'::json, '{"id" : 200}'::json) myjson
UNION ALL
SELECT 'Dingsbums'::text AS name, json_build_array('{"id" : 101}'::json, '{"id" : 201}'::json, '{"id" : 301}'::json) myjson
) t
cross join lateral json_array_elements(myjson) with ordinality as x(element, idx)
您可以使用横向连接(无论如何推荐)和带有顺序性的
SELECT name, x.element ->> 'id' as id, x.idx
FROM (
SELECT 'Dingsda'::text AS name, json_build_array('{"id" : 100}'::json, '{"id" : 200}'::json) myjson
UNION ALL
SELECT 'Dingsbums'::text AS name, json_build_array('{"id" : 101}'::json, '{"id" : 201}'::json, '{"id" : 301}'::json) myjson
) t
cross join lateral json_array_elements(myjson) with ordinality as x(element, idx)
您好,这很有帮助,但在某些情况下,序列在此丢失。请看我的编辑。嗨,这很有帮助,但在某些情况下,序列在这里丢失。请看我的编辑。谢谢,我没有意识到这一点。关键字均不具有顺序性
。非常有帮助!它还保留了数组元素的顺序。谢谢,我没有意识到这一点。关键字均不具有顺序性
。非常有帮助!它还保留了数组元素的顺序。