मैं इसे psql
. में उपयोग करने के लिए विकसित करता हूं .कोड जांचने के लिए मैं छोटा दृश्य बनाता हूं t1
:
CREATE VIEW t1 AS (
SELECT 1 AS id, '{"brother": {"first_name":"Sam", "last_name":"Smith"}, "sister": {"first_name":"Sally", "last_name":"Smith"}}'::jsonb AS jsonb
UNION SELECT 2, '{"sister": {"first_name":"Jill", "last_name":"Johnson"}}'
UNION SELECT 3, '{"sister": {"first_name":"Jill", "x_name":"Johnson"}}'
);
पहला काम संभावित कुंजी की सूची ढूंढना है:
WITH fields AS (
SELECT DISTINCT jff.key
FROM t1,
jsonb_each(jsonb) AS jf,
jsonb_each(jf.value) AS jff
)
SELECT * FROM fields;
नतीजा यह है:
key
------------
first_name
last_name
x_name
अगला चरण क्वेरी उत्पन्न करना है:
SELECT 'SELECT id, jf.key as sibling, ' || (
WITH fields AS (
SELECT DISTINCT jff.key
FROM t1,
jsonb_each(jsonb) AS jf,
jsonb_each(jf.value) AS jff
)
SELECT string_agg('jf.value->>''' || key || ''' as "' || key || '"', ',' ORDER BY key)
FROM fields
)
|| ' FROM t1, jsonb_each(jsonb) AS jf ORDER BY 1, 2, 3;' AS cmd;
यह लौटता है:
cmd
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SELECT id, jf.key as sibling,jf.value->>'first_name' as "first_name",jf.value->>'last_name' as "last_name",jf.value->>'x_name' as "x_name" FROM t1, jsonb_each(jsonb) AS jf ORDER BY 1, 2, 3;
(1 row)
परिणाम को psql चर के रूप में सेट करने के लिए मैं gset
. का उपयोग करता हूं :
\gset
उसके बाद आप क्वेरी को कॉल कर सकते हैं:
:cmd
id | sibling | first_name | last_name | x_name
----+---------+------------+-----------+---------
1 | brother | Sam | Smith |
1 | sister | Sally | Smith |
2 | sister | Jill | Johnson |
3 | sister | Jill | | Johnson
(4 rows)
इसे बाहरी भाषाओं से चलाने के लिए आप रिटर्न SQL कमांड की तुलना में पोस्टग्रेज फंक्शन बना सकते हैं:
CREATE OR REPLACE FUNCTION build_query(IN tname text, OUT cmd text) AS $sql$
BEGIN
EXECUTE $cmd$
SELECT 'SELECT id, jf.key as sibling, ' || (
WITH fields AS (
SELECT DISTINCT jff.key
FROM t1,
jsonb_each(jsonb) AS jf,
jsonb_each(jf.value) AS jff
)
SELECT string_agg('jf.value->>''' || key || ''' as "' || key || '"', ',' ORDER BY key)
FROM fields
)
|| ' FROM $cmd$ || quote_ident(tname) || $cmd$ , jsonb_each(jsonb) AS jf ORDER BY 1, 2, 3;'$cmd$ INTO cmd;
RETURN;
END;
$sql$ LANGUAGE plpgsql;
SELECT * FROM build_query('t1');
cmd
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SELECT id, jf.key as sibling, jf.value->>'first_name' as "first_name",jf.value->>'last_name' as "last_name",jf.value->>'x_name' as "x_name" FROM t1 , jsonb_each(jsonb) AS jf ORDER BY 1, 2, 3;
(1 row)