Postgres JSONb sang XML với tag_name và tag_value

Oct 11 2020

Tôi chưa quen với các hàm XML của Postgres. Tôi có một bảng như sau:

id  (VARCHAR) | field1 (text) | attributes  (jsonb)     
--------------+---------------+----------------------------------

 123          |   a           |   {"age": "1", "place": "TX"}                 
 456          |   b           |   {"age": "2", "name": "abcdef"}     
 789          |               |       
 098          |   c           |   {"name": "gefd"}     

Muốn chuyển đổi nó thành:

 <Company id="123" field="a">
      <CompanyTag tagName="age" tagValue="1"/>
      <CompanyTag tagName="place" tagValue="TX"/>
 </Company>
 <Company id="456" field="b">
      <CompanyTag tagName="age" tagValue="2"/>
      <CompanyTag tagName="name" tagValue="abcdef"/>
 </Company>
 <Company id="789"/>
  <Company id="098" field="c">
      <CompanyTag tagName="name" tagValue="gefd"/>
 </Company>

Có thể dễ dàng chuyển đổi hai cột đầu tiên bằng cách sử dụng bên dưới nhưng JSONb có phần khó khăn nhất:

#SELECT xmlelement(name Company, xmlattributes(id as id, field1 as field)) from comp_emp;;
 <Company id="123" field="a"/>
 <Company id="456" field="b"/>
 <Company id="789"/>
 <Company id="098" field="c"/>

Xin hãy hướng dẫn tôi đi đúng hướng.

Trả lời

2 Bergi Oct 11 2020 at 06:09

Dựa trên giải pháp của @Georges Martin, tôi sẽ không sử dụng phép nối bên và mệnh đề nhóm, mà chỉ sử dụng một truy vấn con lồng nhau:

SELECT XMLELEMENT(
  NAME "Company", 
  XMLATTRIBUTES(id AS id, field1 AS field), 
  (SELECT XMLAGG(
    XMLELEMENT(
      NAME "companyTag", 
      XMLATTRIBUTES(
        attr.key AS "tagName", 
        attr.value AS "tagValue"
      )
    )
  ) FROM JSONB_EACH_TEXT(attributes) AS attr)
) FROM comp_emp;

( bản demo trực tuyến )

1 GeorgesMartin Oct 11 2020 at 05:53

Đây là một giải pháp một phần vì tôi đã quên field1cột nhưng điều này:

SELECT 
 XMLELEMENT(
  NAME "Company", 
  XMLATTRIBUTES(id AS id), 
  XMLAGG(
   XMLELEMENT(
    NAME "CompanyTag", 
    XMLATTRIBUTES(
     (attr).key AS "tagName", 
     (attr).value AS "tagValue"
    )
   )
  )
 ) 
FROM (
 SELECT 
  id, JSONB_EACH_TEXT(attributes) AS attr 
 FROM comp_emp
) AS sub 
GROUP BY id;

đã trở lại:

<Company id="098">
  <CompanyTag tagName="name" tagValue="gefd"/>
</Company>
<Company id="456">
  <CompanyTag tagName="age" tagValue="2"/>
  <CompanyTag tagName="name" tagValue="abcdef"/>
</Company>
<Company id="123">
  <CompanyTag tagName="age" tagValue="1"/>
  <CompanyTag tagName="place" tagValue="TX"/>
</Company>