Bạn có thể đạt được điều này với một số hàm json có sẵn trong postgresql.
Trong ví dụ với db-fiddle đang hoạt động bên dưới, tôi đã bao gồm một số dữ liệu thử nghiệm bổ sung.
Giản đồ (PostgreSQL v13)
CREATE TABLE my_table (
"dest" json
);
INSERT INTO my_table
("dest")
VALUES
('{"DestinationLists": [{"name": "TV3/TVNZ/CHOICE", "destinations": [183, 165]}]}'),
('{"DestinationLists": [{"name": "SecondTest", "destinations": [103, 105]},{"name": "ThirdTest", "destinations": [3, 5]}]}');
Truy vấn số 1
WITH expanded_data AS (
SELECT
dest::text,
json_build_object(
'name',
dl->>'name',
'destinations',
json_agg(
json_build_object('Id',dld::text::int)
)
) as dest_list_item
FROM
my_table,
json_array_elements(dest->'DestinationLists') dl,
json_array_elements(dl->'destinations') dld
GROUP BY
dest::text,dl->>'name'
)
SELECT
json_build_object(
'DestinationLists',
json_agg(dest_list_item)
) as new_dest
FROM
expanded_data
GROUP BY
dest::text;
new_dest |
---|
{"DestinationLists":[{"name":"ThirdTest", "Destination":[{"Id":3}, {"Id":5}]}, {"name ":" Thử nghiệm thứ hai "," đích ":[{" Id ":103}, {" Id ":105}]}]} |
{"Danh sách đích":[{"name":"TV3 / TVNZ / CHOICE", "điểm đến":[{"Id":183}, {"Id":165}]}]} |
Chỉnh sửa 1
Để đáp lại chỉnh sửa của bạn, mã dưới đây có thể được sử dụng làm bản cập nhật từ tuyên bố. NB. CTE cũng có thể được viết lại dưới dạng một truy vấn con. Vui lòng xem ví dụ bên dưới:
Giản đồ (PostgreSQL v13)
CREATE TABLE my_table (
id bigserial,
"dest" jsonb
);
INSERT INTO my_table
("dest")
VALUES
('{"DestinationLists": [{"name": "TV3/TVNZ/CHOICE", "destinations": [183, 165]}]}'),
('{"DestinationLists": [{"name": "SecondTest", "destinations": [103, 105]},{"name": "ThirdTest", "destinations": [3, 5]}]}');
WITH expanded_data AS (
SELECT
id,
json_build_object(
'name',
dl->>'name',
'destinations',
json_agg(
json_build_object('Id',dld::text::int)
)
) as dest_list_item
FROM
my_table,
jsonb_array_elements(dest->'DestinationLists') dl,
jsonb_array_elements(dl->'destinations') dld
GROUP BY
id,dl->>'name'
),
new_json AS (
SELECT
id,
json_build_object(
'DestinationLists',
json_agg(dest_list_item)
) as new_dest
FROM
expanded_data
GROUP BY
id
)
UPDATE my_table
SET dest = new_json.new_dest
FROM new_json
WHERE my_table.id = new_json.id;
Sau
SELECT * FROM my_table;
id | cuối cùng |
---|---|
1 | {"DestinationLists":[{"name":"TV3 / TVNZ / CHOICE", "destination":[{"Id":183}, {"Id":165}]}]} |
2 | {"DestinationLists":[{"name":"SecondTest", "Destination":[{"Id":103}, {"Id":105}]}, {"name":"ThirdTest", "đích":[{"Id":3}, {"Id":5}]}]} |
Chỉnh sửa 2
Chỉnh sửa này giải quyết các trường hợp phức tạp trong đó một số điểm đến có thể không có điểm đến và như vậy có thể không được cập nhật.
Để kiểm tra, hai bản ghi bổ sung đã được thêm vào, bản ghi mẫu được cung cấp trong đó có hai danh sách điểm đến được đặt tên nhưng chỉ một bản ghi có điểm đến và một bản ghi khác có danh sách điểm đến được đặt tên không có điểm đến.
Bản cập nhật đảm bảo rằng nếu không có thay đổi nào, có nghĩa là danh sách điểm đến đã được đặt tên mà không có điểm đến nào được giữ nguyên. Nó đảm bảo điều này bằng cách kiểm tra xem số lượng các mục danh sách đích đã đặt tên có giống với số lượng các mục danh sách đích trống không. Vì tất cả đều trống, nó lọc bản ghi này khỏi bản cập nhật và giảm số lượng bản cập nhật cần thiết trên cơ sở dữ liệu. Ví dụ về điều này là bản ghi số 4
Truy vấn ban đầu đã được sửa đổi để phù hợp với các danh sách trống này khi chúng đang được lọc bằng cách tiếp cận trước đó.
Giản đồ (PostgreSQL v13)
CREATE TABLE my_table (
id bigserial,
"dest" jsonb
);
INSERT INTO my_table
("dest")
VALUES
('{"DestinationLists": [{"name": "TV3/TVNZ/CHOICE", "destinations": [183, 165]}]}'),
('{"DestinationLists": [{"name": "SecondTest", "destinations": [103, 105]},{"name": "ThirdTest", "destinations": [3, 5]}]}'),
('{"DestinationLists": [{"name": "TVNZ, Mediaworks, Choice", "destinations": []}, {"name": "TVNZ, Discovery", "destinations": [165, 183, 4155]}]}'),
('{"DestinationLists": [{"name": "Fourth Test", "destinations": []}]}');
Truy vấn số 1
SELECT '------ BEFORE -----';
cột ? |
---|
------ TRƯỚC ----- |
Truy vấn số 2
SELECT * FROM my_table;
id | cuối cùng |
---|---|
1 | {"Danh sách đích":[{"name":"TV3 / TVNZ / CHOICE", "điểm đến":[183,165]}]} |
2 | {"Danh sách đích":[{"tên":"Thử nghiệm thứ hai", "điểm đến":[103,105]}, {"tên":"Thử nghiệm thứ ba", "điểm đến":[3,5]}]} |
3 | {"Danh sách điểm đến":[{"tên":"TVNZ, Mediaworks, Sự lựa chọn", "điểm đến":[]}, {"tên":"TVNZ, Khám phá", "điểm đến":[165,183,4155] }]} |
4 | {"Danh sách đích":[{"name":"Thử nghiệm lần thứ tư", "điểm đến":[]}]} |
Truy vấn số 3
WITH expanded_data AS (
SELECT
id,
CASE
WHEN COUNT(dld)=0 THEN 1
ELSE 0
END as name_has_empty_list_item,
json_build_object(
'name',
dl->>'name',
'destinations',
CASE
WHEN
COUNT(dld)=0
THEN
to_json(array[]::json[])
ELSE
json_agg(
json_build_object('Id',dld::text::int )
)
END
) as dest_list_item
FROM
my_table,
jsonb_array_elements(dest->'DestinationLists') dl
LEFT JOIN
jsonb_array_elements(dl->'destinations') dld ON 1=1
GROUP BY
id,dl->>'name'
),
new_json AS (
SELECT
id,
COUNT(dest_list_item) as no_list_item,
SUM(name_has_empty_list_item) as no_empty_list_item,
json_build_object(
'DestinationLists',
json_agg(dest_list_item)
) as new_dest
FROM
expanded_data
GROUP BY
id
HAVING
SUM(name_has_empty_list_item) <> COUNT(dest_list_item)
)
SELECT * FROM new_json;
id | no_list_item | no_empty_list_item | new_dest |
---|---|---|---|
1 | 1 | 0 | {"DestinationLists":[{"name":"TV3 / TVNZ / CHOICE", "destination":[{"Id":183}, {"Id":165}]}]} |
2 | 2 | 0 | {"DestinationLists":[{"name":"SecondTest", "Destination":[{"Id":103}, {"Id":105}]}, {"name":"ThirdTest", "đích":[{"Id":3}, {"Id":5}]}]} |
3 | 2 | 1 | {"DestinationLists":[{"name":"TVNZ, Discovery", "destination":[{"Id":165}, {"Id":183}, {"Id":4155}]} , {"name":"TVNZ, Mediaworks, Choice", "đích":[]}]} |
Truy vấn số 4
WITH expanded_data AS (
SELECT
id,
CASE
WHEN COUNT(dld)=0 THEN 1
ELSE 0
END as name_has_empty_list_item,
json_build_object(
'name',
dl->>'name',
'destinations',
CASE
WHEN
COUNT(dld)=0
THEN
to_json(array[]::json[])
ELSE
json_agg(
json_build_object('Id',dld::text::int )
)
END
) as dest_list_item
FROM
my_table,
jsonb_array_elements(dest->'DestinationLists') dl
LEFT JOIN
jsonb_array_elements(dl->'destinations') dld ON 1=1
GROUP BY
id,dl->>'name'
),
new_json AS (
SELECT
id,
json_build_object(
'DestinationLists',
json_agg(dest_list_item)
) as new_dest
FROM
expanded_data
GROUP BY
id
HAVING
SUM(name_has_empty_list_item) <> COUNT(dest_list_item)
)
UPDATE my_table
SET dest = new_json.new_dest
FROM new_json
WHERE my_table.id = new_json.id;
Không có kết quả nào được hiển thị.
Truy vấn số 5
SELECT '------ AFTER -----';
cột ? |
---|
------ SAU ----- |
Truy vấn số 6
SELECT * FROM my_table;
id | cuối cùng |
---|---|
4 | {"DestinationLists":[{"name":"Thử nghiệm lần thứ tư", "điểm đến":[]}]} |
1 | {"DestinationLists":[{"name":"TV3 / TVNZ / CHOICE", "destination":[{"Id":183}, {"Id":165}]}]} |
2 | {"DestinationLists":[{"name":"SecondTest", "Destination":[{"Id":103}, {"Id":105}]}, {"name":"ThirdTest", "đích":[{"Id":3}, {"Id":5}]}]} |
3 | {"DestinationLists":[{"name":"TVNZ, Discovery", "destination":[{"Id":165}, {"Id":183}, {"Id":4155}]} , {"name":"TVNZ, Mediaworks, Choice", "đích":[]}]} |
Hãy cho tôi biết nếu điều này phù hợp với bạn.