monika
monika

Reputation: 67

Select query using json format value

If customer first_name-'Monika', last_name='Awasthi'

Then I am using below query to return value in json format:

SELECT * 
  FROM
  (
   SELECT JSON_ARRAYAGG(JSON_OBJECT('CODE' IS '1','VALUE' IS 'Monika'||' '||'Awasthi'))
     FROM DUAL 
  );
        

It is working fine & give below output:

[{"CODE":"1","VALUE":"Monika Awasthi"}]

But I want one more value which should be reversed means output should be:

[{"CODE":"1","VALUE":"Monika Awasthi"},{"CODE":"2","VALUE":"Awasthi Monika"}]

Kindly give me some suggestions. Thank You

Upvotes: 1

Views: 1273

Answers (3)

user5683823
user5683823

Reputation:

As I explained in a comment under your question, I am not clear on how you define the CODE values for your JSON string (assuming you have more than one customer).

Other than that, if you need to create a JSON array of objects from individual strings (as in your attempt), you probably need to use JSON_ARRAY rather than JSON_ARRAYAGG. Something like I show below. Incidentally, I also don't know why you needed to SELECT * FROM (subquery) - the outer SELECT seems entirely unnecessary.

So, if you don't actually aggregate over a table, but just need to build a JSON array from individual pieces:

select json_array
       (
         json_object('CODE' is '1', 'VALUE' is first_name || ' ' || last_name ),
         json_object('CODE' is '2', 'VALUE' is last_name  || ' ' || first_name)
       ) as result
from   ( select 'Monika' as first_name, 'Awasthi' as last_name from dual )
;

RESULT                                                                        
------------------------------------------------------------------------------
[{"CODE":"1","VALUE":"Monika Awasthi"},{"CODE":"2","VALUE":"Awasthi Monika"}]

Upvotes: 1

Barbaros Özhan
Barbaros Özhan

Reputation: 65408

A simple logic through use of SQL(without using PL/SQL) in order to generate code values as only be usable for two columns as in this case might be

SELECT JSON_ARRAYAGG(
          JSON_OBJECT('CODE' IS tt.column_id,
                      'VALUE' IS CASE WHEN column_id=1 
                                      THEN name||' '||surname
                                      ELSE surname||' '||name
                                       END)
                    ) AS result
  FROM t
 CROSS JOIN (SELECT column_id FROM user_tab_cols WHERE table_name =  'T') tt

where t is a table which hold name and surname columns

Demo

More resilient solution might be provided through use of PL/SQL, even more columns exist within the data source such as

DECLARE
 v_jso   VARCHAR2(4000);
 v_arr   OWA.VC_ARR; 
 v_arr_t JSON_ARRAY_T := JSON_ARRAY_T(); 
BEGIN
 FOR c IN ( SELECT column_id FROM user_tab_cols WHERE table_name = 'T' )
 LOOP
   SELECT 'JSON_OBJECT( ''CODE'' IS '||MAX(c.column_id)||',
                        ''VALUE'' IS '||LISTAGG(column_name,'||'' ''||') 
                                        WITHIN GROUP (ORDER BY ABS(column_id-c.column_id))
                                        ||' )'
     INTO v_arr(c.column_id)                                   
     FROM ( SELECT * FROM user_tab_cols WHERE table_name = 'T' );

   EXECUTE IMMEDIATE 'SELECT '||v_arr(c.column_id)||' FROM t' INTO v_jso;
   v_arr_t.APPEND(JSON_OBJECT_T(v_jso));
 END LOOP;

 DBMS_OUTPUT.PUT_LINE(v_arr_t.STRINGIFY);  
 
END;
/

Demo

Upvotes: 2

Alex Poole
Alex Poole

Reputation: 191570

Another approach is to use a CTE to generate the two codes and values; your original version could be written to get the name data from a table or CTE:

-- CTE for sample data
WITH cte (first_name, last_name) AS (
  SELECT 'Monika', 'Awasthi' FROM DUAL
)
-- query against CTE or table
SELECT JSON_ARRAYAGG(JSON_OBJECT('CODE' IS '1','VALUE' IS last_name ||' '|| first_name))
FROM cte;

And you could then extend that with a CTE that generates the value with the names in both orders:

WITH cte1 (first_name, last_name) AS (
  SELECT 'Monika', 'Awasthi' FROM DUAL
),
cte2 (code, value) AS (
  SELECT 1 AS code, first_name || ' ' || last_name FROM cte1
  UNION ALL
  SELECT 2 AS code, last_name || ' ' || first_name FROM cte1
)
SELECT JSON_ARRAYAGG(JSON_OBJECT('CODE' IS code,'VALUE' IS value))
FROM cte2;

which gives:

JSON_ARRAYAGG(JSON_OBJECT('CODE'ISCODE,'VALUE'ISVALUE))
-------------------------------------------------------------------------
[{"CODE":1,"VALUE":"Monika Awasthi"},{"CODE":2,"VALUE":"Awasthi Monika"}]

db<>fiddle

Upvotes: 2

Related Questions