Postgres 9.4 หรือใหม่กว่า
เห็นได้ชัดว่าได้แรงบันดาลใจจากโพสต์นี้ Postgres 9.4 ได้เพิ่มฟังก์ชั่นที่หายไป:
ขอบคุณ Laurence Rowe สำหรับแพทช์และ Andrew Dunstan ที่ทำหน้าที่!
ในการเลิกใช้อาร์เรย์ JSON จากนั้นใช้array_agg()
หรือตัวสร้าง ARRAYเพื่อสร้างอาร์เรย์ Postgres จากมัน หรือstring_agg()
การสร้างสตริงtext
รวมองค์ประกอบที่ไม่ได้ทดสอบต่อแถวในLATERAL
แบบสอบถามย่อยที่มีความสัมพันธ์หรือ แล้วคำสั่งเดิมจะถูกรักษาไว้และที่เราไม่จำเป็นต้องORDER BY
, GROUP BY
หรือแม้กระทั่งคีย์ไม่ซ้ำกันในแบบสอบถามด้านนอก ดู:
แทนที่ 'json' ด้วย 'jsonb' สำหรับjsonb
ในรหัส SQL ต่อไปนี้ทั้งหมด
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;
ไวยากรณ์สั้น:
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;
ที่เกี่ยวข้อง:
ตัวสร้าง ARRAY ในแบบสอบถามย่อยที่มีความสัมพันธ์:
SELECT tbl_id, ARRAY(SELECT json_array_elements_text(t.data->'tags')) AS txt_arr
FROM tbl t;
ที่เกี่ยวข้อง:
เมตตาความแตกต่าง : null
องค์ประกอบถูกเก็บไว้ในที่เกิดขึ้นจริงอาร์เรย์ สิ่งนี้เป็นไปไม่ได้ในข้อความค้นหาด้านบนที่สร้างtext
สตริงซึ่งไม่สามารถมีnull
ค่าได้ การเป็นตัวแทนที่แท้จริงคืออาร์เรย์
ฟังก์ชั่นกระดาษห่อ
สำหรับการใช้งานซ้ำ ๆ เพื่อทำให้สิ่งนี้ง่ายยิ่งขึ้น encapsulate ลอจิกในฟังก์ชัน:
CREATE OR REPLACE FUNCTION json_arr2text_arr(_js json)
RETURNS text[] LANGUAGE sql IMMUTABLE AS
'SELECT ARRAY(SELECT json_array_elements_text(_js))';
ทำให้มันเป็นฟังก์ชั่น SQLดังนั้นมันสามารถถูกแทรกในเคียวรีที่ใหญ่กว่า
ทำให้เป็นIMMUTABLE
(เพราะเป็น) เพื่อหลีกเลี่ยงการประเมินซ้ำในแบบสอบถามที่ใหญ่กว่าและอนุญาตให้แสดงในดัชนี
โทร:
SELECT tbl_id, json_arr2text_arr(data->'tags')
FROM tbl;
db <> ซอที่นี่
โพสต์ 9.3 หรือเก่ากว่า
json_array_elements()
ใช้ฟังก์ชั่น แต่เราได้สตริงที่ยกมาสองเท่าจากมัน
แบบสอบถามทางเลือกที่มีการรวมในแบบสอบถามด้านนอก CROSS JOIN
ลบแถวที่มีอาร์เรย์ที่หายไปหรือว่างเปล่า อาจเป็นประโยชน์สำหรับองค์ประกอบการประมวลผล เราต้องการรหัสที่ไม่ซ้ำเพื่อรวม:
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;
ตัวสร้าง ARRAY ยังคงมีสตริงที่เสนอ:
SELECT tbl_id, ARRAY(SELECT json_array_elements(t.data->'tags')) AS quoted_txt_arr
FROM tbl t;
โปรดทราบว่าnull
จะถูกแปลงเป็นค่าข้อความ "null" ไม่เหมือนข้างบน ไม่ถูกต้องพูดอย่างเคร่งครัดและอาจคลุมเครือ
คนจนไม่น่าสงสัยด้วย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;
ดึงแถวเดียวจาก 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;
สตริงย่อยฟอร์มแบบสอบถามที่สัมพันธ์กัน:
SELECT tbl_id, (SELECT string_agg(trim(value::text, '"'), ', ')
FROM json_array_elements(t.data->'tags')) AS list
FROM tbl t;
ตัวสร้าง ARRAY:
SELECT tbl_id, ARRAY(SELECT trim(value::text, '"')
FROM json_array_elements(t.data->'tags')) AS txt_arr
FROM tbl t;
ต้นฉบับ (เก่า) SQL ซอ
db <> ซอที่นี่
ที่เกี่ยวข้อง:
หมายเหตุ (ล้าสมัยตั้งแต่ pg 9.4)
เราต้องการ a json_array_elements_text(json)
, คู่ของjson_array_elements(json)
เพื่อส่งคืนtext
ค่าที่เหมาะสมจากอาร์เรย์ JSON แต่ที่ดูเหมือนว่าจะหายไปจากคลังแสงที่มีให้ฟังก์ชั่น JSON หรือฟังก์ชันอื่นเพื่อแยกtext
ค่าจากJSON
ค่าสเกลาร์ ฉันก็ดูเหมือนจะขาดหายไปเช่นกัน
ดังนั้นฉันชั่วคราวด้วยtrim()
แต่จะล้มเหลวสำหรับกรณีที่ไม่สำคัญ ...
json_extract_path_text(your_column, 'tags')
สิ่งที่คุณกำลังมองหา?