Начало » Использование СУБД » PostgreSQL » Массово заменить ключ в jsonb
| Массово заменить ключ в jsonb [сообщение #6330] |
Wed, 08 April 2026 14:41  |
polin11
Сообщений: 11 Зарегистрирован: January 2023
|
Junior Member |
|
|
Использую PGSQL 16.
Есть основная таблица
CREATE TABLE product (
doc_id INT,
details JSONB
);
INSERT INTO product VALUES (1, '{"CPU":4, "RAM":16, "HDD":2}');
INSERT INTO product VALUES (2, '{"CPU":3, "RAM":8, "HDD":1}');
doc_id | details
----+---------------------------------
1 | {"CPU": 4, "HDD": 2, "RAM": 16}
2 | {"CPU": 3, "HDD": 1, "RAM": 8}
Также есть таблица соотв. для замены товара
CREATE TABLE replace (
id INT,
doc_id INT,
old_key text,
new_key text
);
INSERT INTO replace VALUES (1, 1, 'CPU', 'RAM');
INSERT INTO replace VALUES (2, 1, 'HDD', 'SSD');
INSERT INTO replace VALUES (3, 2, 'HDD', 'SSD');
id | doc_id | old_key | new_key
----+--------+---------+---------
1 | 1 | CPU | RAM
2 | 1 | HDD | SSD
3 | 2 | HDD | SSD
Нужно в таблице product в JSONB заменить старый ключ на новый ключ, если новый ключ уже есть в JSONB, то значения
старого и нового ключей нужно сложить,
то есть после замены должны получить такие данные product:
id | details
----+---------------------------------
1 | {"SSD": 2, "RAM": 20}
2 | {"CPU": 3, "SSD": 1, "RAM": 8}
У меня нет идей как это можно сделать, помогите пож-ста написать такой запрос
|
|
|
|
| Re: Массово заменить ключ в jsonb [сообщение #6344 является ответом на сообщение #6330] |
Fri, 01 May 2026 21:28  |
BlackEric
Сообщений: 394 Зарегистрирован: June 2022
|
Senior Member |
|
|
WITH upd AS (
SELECT
p.doc_id,
jsonb_object_agg(
COALESCE(r.new_key, key), -- если есть замена, берем new_key
CASE
WHEN r.new_key IS NOT NULL AND p.details ? r.new_key
THEN ( (p.details ->> key)::int + (p.details ->> r.new_key)::int )::text::jsonb
ELSE value
END
) AS new_details
FROM product p
LEFT JOIN replace r
ON p.doc_id = r.doc_id AND (p.details ? r.old_key)
CROSS JOIN LATERAL jsonb_each(p.details)
WHERE r.old_key IS NULL OR key = r.old_key
GROUP BY p.doc_id
)
UPDATE product AS p
SET details = u.new_details
FROM upd u
WHERE p.doc_id = u.doc_id;
|
|
|
|
Переход к форуму:
Текущее время: Fri May 01 22:26:54 GMT+3 2026
Общее время, затраченное на создание страницы: 0.00712 секунд
|