У меня есть таблица в PostgreSQL с некоторыми данными:
create table t2 (
key jsonb,
value jsonb
);
INSERT INTO t2(key, value)
VALUES
('1', '"test 1"')
,('2', '"test 2"')
,('3', '"test 3"')
,('[]', '"test 4"')
,('[1]', '"test 5"')
,('[2]', '"test 6"')
,('[3]', '"test 7"')
,('[1, 2]', '"test 8"')
,('[1, 2, 3]', '"test 9"')
,('[1, 3]', '"test 10"')
,('[1,2,4]', '"test 11"')
,('[1, 2,4]', '"test 12"')
,('[1,3,13]', '"test 13"')
,('[1, 2, 15]', '"test 15"');
И я пытаюсь отсортировать эти строки следующим образом:
SELECT key FROM t2 order by key;
Результат:
[]
1
2
3
[1]
[2] <==
[3] <==
[1, 2]
[1, 3] <==
[1, 2, 3]
[1, 2, 4]
[1, 2, 4]
[1, 2, 15]
[1, 3, 13]
Но то, что мне нужно, это:
[]
1
2
3
[1]
[1, 2]
[1, 2, 3]
[1, 2, 4]
[1, 2, 4]
[1, 2, 15]
[1, 3] <==
[1, 3, 13]
[2] <==
[3] <==
Есть ли способ добиться этого?
Ответы:
Во-первых, ваш вопрос и название столбца
"key"
вводят в заблуждение. Ключ столбца не содержит ключей JSON , только значения . В противном случае мы могли бы использовать функциюjsonb_object_keys(jsonb)
для извлечения ключей, но это не так.Предполагая, что все ваши массивы JSON либо пусты, либо содержат целые числа, как показано. И скалярные значения (не массивы) также являются целочисленными.
Ваш основной порядок сортировки будет работать с массивами Postgres
integer
(илиnumeric
). Я использую эту маленькую вспомогательную функцию для преобразованияjsonb
массивов в Postgresint[]
:Объяснение:
Затем добавьте,
jsonb_typeof(jsonb)
чтобы получить:Дает желаемый результат точно.
Почему?
Руководство
jsonb
объясняет:Жирный акцент мой.
Вот почему
jsonb '[2]' < jsonb '[1, 2]'
.Но массивы Postgres просто сортируют поэлементно:
'{2}'::int[] > '{1, 2}'
- именно то, что вы искали.источник
Обращаясь к задаче упорядочить результаты по целочисленным значениям json. Пытаться:
В вашем случае это, кажется, массив для ключа заказа. Поэтому сначала попробуйте объединить значения в поле «ключ».
источник