Đặt tên thành thuộc tính khi tạo JSON bằng row_to_json


24

Có thể đổi tên tên mặc định f1, f2, f3...khi chỉ sử dụng row_to_jsonhàm cho một số cột không?

tôi có thể làm

row_to_json(customers)

trở về

{"id_customer":2,"first_name":"bla","last_name":"second_bla"}

Nhưng nếu tôi chỉ muốn tên mà không có id_customer, tôi phải sử dụng

row_to_json(row(first_name, last_name))

và sau đó tôi nhận được

{"f1":"bla","f2":"second_bla"}

Và tôi muốn có được kết quả này với tên cột mặc định hoặc tên riêng của tôi. Tôi biết tôi có thể tạo loại hỗn hợp của riêng mình và sử dụng

row_to_json(row(first_name, last_name))::my_custom_type

nhưng không thể thực hiện nó ngay trong truy vấn mà không tạo kiểu đó?


1
Ngoài ra, xem: tham chiếu 1tham chiếu 2 cho tương tự
MikeM

Câu trả lời:


17

Biểu thức bảng chung cho phép bạn xác định rõ các bí danh, không chỉ cho CTE mà còn cho các cột của nó.

WITH data(col1,col2,cola,colb) AS (
  VALUES (1,2,'fred','bob')
)
SELECT row_to_json(data) FROM data;

Điều này khác với ví dụ của @ dezso ở chỗ nó không sử dụng col AS aliascho mỗi col trong SELECTdanh sách; nó bí danh các tên cột trong bí danh bảng CTE.

Tôi đã sử dụng một VALUESbiểu thức như một truy vấn con nhưng bạn có thể sử dụng SELECTbất cứ thứ gì bạn thích; điểm quan trọng là bất kỳ bí danh cột nào được cung cấp hoặc giả định trong truy vấn con đều có thể được ghi đè trong định nghĩa CTE bằng cách chỉ định danh sách tên cột.

Bạn có thể làm điều tương tự trong truy vấn con, thay vì sử dụng AS alias:

SELECT row_to_json(data) 
FROM (VALUES (1,2,'fred','bob')) data(col1,col2,cola,colb);

Điều này không làm việc với một ROWbiểu thức trực tiếp; bạn chỉ có thể ROWchuyển một loại cụ thể, bạn không thể đặt bí danh cho nó.

regress=> SELECT ROW(1,2,'fred','bob') AS x(a,b,c,d);
ERROR:  syntax error at or near "("
LINE 1: SELECT ROW(1,2,'fred','bob') AS x(a,b,c,d);

Có sự khác biệt nào (ngoài phong cách và / hoặc khả năng đọc) giữa các giải pháp của chúng tôi (cách sử dụng, hiệu suất, v.v.) không?
dezso

@dezso Không, và có lẽ tôi nên đăng một bình luận. Lấy làm tiếc.
Craig Ringer

Tôi nghĩ rằng điều này là OK. Tôi thậm chí còn nêu lên câu trả lời của bạn vì nó chứa thông tin hữu ích mà tôi không biết.
dezso

Có một cú pháp để có được các bí danh cột động? Tôi đang lấy từ một lược đồ EAV (giá trị thuộc tính thực thể) trong đó các tên khóa mong muốn cũng được chọn từ cột property.name.
Chris

@Chris Bạn sẽ cần các hàm json tinh vi hơn trong 9.4.
Craig Ringer

23
select 
   c.id,
   (select row_to_json(_) from (select c.first_name, c.last_name) as _) as first_last,
   c.age
from
   customers as c

sẽ làm những gì bạn muốn mà không có bất kỳ tác động hiệu suất nào (và không quá dài dòng):

  id  |   first_last                                |   age
------+---------------------------------------------+---------
  1   | {"fisrt_name": "John", "last_name": "Smit"} |   34

4
Câu trả lời này là một viên đá quý.
tiffon

Cảm ơn rất nhiều bạn đã lưu buổi chiều của tôi, thật tệ vì đây không phải là một ví dụ được trích dẫn trong API PostgreQuery. Tôi biết điều đó là có thể
jlandercy

9

Bạn có thể làm một cái gì đó như thế này:

WITH r AS (
  SELECT 'bla' AS name1, 'otherbla' AS name2
)
SELECT row_to_json(r.*)
FROM r
;

(Tất nhiên, điều tương tự có thể đạt được với

SELECT row_to_json(r.*)
FROM (SELECT 'bla' AS name1, 'otherbla' AS name2) r
;

nhưng tôi thấy cái trước dễ đọc hơn.)

Trong WITHphần bạn có thể xây dựng các hàng của bất kỳ cấu trúc nào đang bay.


Để ghép nối non-jsonb với jsonb :: SELECT row_to_json (r. *) TỪ (CHỌN c1, c2 :: jsonb TỪ us_ca_monterey_aoc.test) là r
Andrew Scott Evans

9

Bạn có thể sử dụng json_build_object.

SELECT 
  json_build_object('id', data.customer_id, 'first_name', data.first_name, 'last_name', data.last_name) as your_json
FROM data;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.