Postgres 9,4 hoặc mới hơn
Rõ ràng lấy cảm hứng từ bài đăng này , Postgres 9.4 đã thêm (các) chức năng còn thiếu:
Cảm ơn Laurence Rowe cho bản vá và Andrew Dunstan đã cam kết!
Để hủy bỏ mảng JSON. Sau đó sử dụng array_agg()
hoặc một hàm tạo ARRAY để xây dựng một mảng Postgres từ nó. Hoặc string_agg()
để xây dựng một text
chuỗi .
Tổng hợp các phần tử không được kiểm tra trên mỗi hàng trong một LATERAL
truy vấn con tương quan. Sau đó, thứ tự ban đầu được giữ nguyên và chúng tôi không cần ORDER BY
, GROUP BY
hoặc thậm chí là một khóa duy nhất trong truy vấn bên ngoài. Xem:
Thay thế 'json' bằng 'jsonb' jsonb
trong tất cả các mã SQL sau.
SELECT t.tbl_id, d.list
FROM tbl t
CROSS JOIN LATERAL (
SELECT string_agg(d.elem::text, ', ') AS list
FROM json_array_elements_text(t.data->'tags') AS d(elem)
) d;
Cú pháp ngắn:
SELECT t.tbl_id, d.list
FROM tbl t, LATERAL (
SELECT string_agg(value::text, ', ') AS list
FROM json_array_elements_text(t.data->'tags') -- col name default: "value"
) d;
Liên quan:
Trình xây dựng ARRAY trong truy vấn con tương quan:
SELECT tbl_id, ARRAY(SELECT json_array_elements_text(t.data->'tags')) AS txt_arr
FROM tbl t;
Liên quan:
Sự khác biệt tinh tế : null
các yếu tố được bảo tồn trong các mảng thực tế . Điều này là không thể trong các truy vấn trên tạo ra một text
chuỗi, không thể chứa null
các giá trị. Các đại diện thực sự là một mảng.
Chức năng bao bọc
Để sử dụng nhiều lần, để làm cho điều này thậm chí đơn giản hơn, hãy gói gọn logic trong một hàm:
CREATE OR REPLACE FUNCTION json_arr2text_arr(_js json)
RETURNS text[] LANGUAGE sql IMMUTABLE AS
'SELECT ARRAY(SELECT json_array_elements_text(_js))';
Làm cho nó trở thành một hàm SQL , để nó có thể được nội tuyến trong các truy vấn lớn hơn.
Làm cho nó IMMUTABLE
(bởi vì nó là) để tránh đánh giá lặp đi lặp lại trong các truy vấn lớn hơn và cho phép nó trong các biểu thức chỉ mục.
Gọi:
SELECT tbl_id, json_arr2text_arr(data->'tags')
FROM tbl;
db <> fiddle ở đây
Postgres 9.3 trở lên
Sử dụng chức năng json_array_elements()
. Nhưng chúng tôi nhận được chuỗi trích dẫn gấp đôi từ nó.
Truy vấn thay thế với tổng hợp trong truy vấn bên ngoài. CROSS JOIN
loại bỏ các hàng có mảng bị thiếu hoặc trống. Cũng có thể hữu ích cho việc xử lý các yếu tố. Chúng tôi cần một khóa duy nhất để tổng hợp:
SELECT t.tbl_id, string_agg(d.elem::text, ', ') AS list
FROM tbl t
CROSS JOIN LATERAL json_array_elements(t.data->'tags') AS d(elem)
GROUP BY t.tbl_id;
Trình xây dựng ARRAY, vẫn có các chuỗi được trích dẫn:
SELECT tbl_id, ARRAY(SELECT json_array_elements(t.data->'tags')) AS quoted_txt_arr
FROM tbl t;
Lưu ý rằng null
được chuyển đổi thành giá trị văn bản "null", không giống như ở trên. Không chính xác, nói đúng, và có khả năng mơ hồ.
Người đàn ông nghèo không có quyền với trim()
:
SELECT t.tbl_id, string_agg(trim(d.elem::text, '"'), ', ') AS list
FROM tbl t, json_array_elements(t.data->'tags') d(elem)
GROUP BY 1;
Lấy một hàng từ tbl:
SELECT string_agg(trim(d.elem::text, '"'), ', ') AS list
FROM tbl t, json_array_elements(t.data->'tags') d(elem)
WHERE t.tbl_id = 1;
Chuỗi hình thành truy vấn con tương quan:
SELECT tbl_id, (SELECT string_agg(trim(value::text, '"'), ', ')
FROM json_array_elements(t.data->'tags')) AS list
FROM tbl t;
Nhà xây dựng ARRAY:
SELECT tbl_id, ARRAY(SELECT trim(value::text, '"')
FROM json_array_elements(t.data->'tags')) AS txt_arr
FROM tbl t;
Fiddle SQL gốc (lỗi thời) .
db <> fiddle ở đây.
Liên quan:
Ghi chú (lỗi thời kể từ trang 9,4)
Chúng ta sẽ cần một json_array_elements_text(json)
cặp sinh đôi json_array_elements(json)
để trả về các text
giá trị phù hợp từ một mảng JSON. Nhưng điều đó dường như bị thiếu trong kho vũ khí được cung cấp của các hàm JSON . Hoặc một số hàm khác để trích xuất một text
giá trị từ JSON
giá trị vô hướng . Tôi dường như đang thiếu cái đó
Vì vậy, tôi đã ứng biến trim()
, nhưng điều đó sẽ thất bại đối với những trường hợp không tầm thường ...
json_extract_path_text(your_column, 'tags')
những gì bạn đang tìm kiếm?