1

i have a table which contains JSON value and i have manipulated it using the below query,If i specify each column separately then the query will work fine, rather than i want it to be dynamic ,so that if i have added any columns to the JSON string then it will automatically take that corresponding column.

So how can i execute the below generated dynamic query in PostgreSQL?

have tried using EXECUTE but it's showing syntax error near SELECT.

Any suggestions would be of great help.

-- THE CTE will get all the created columns in the JSON string,So if someone add a new column it will take that new column.

WITH CTE AS
(
    SELECT DISTINCT
        elems ->> 'name' AS column_name
    , 'MAX(value) FILTER (WHERE column_name = ''' || CAST(elems ->> 'name' as TEXT) || ''') as '|| CAST(elems ->> 'name' as TEXT) 
      as selected_customfields

FROM
        dl_get_response.gr_contacts,
        json_array_elements( "customFieldValues"::json) elems
)
-- below is the actual query i want to execute,The result of the custom_query CTE need to be executed 
,custom_query as 
(
    SELECT '''SELECT ' || string_agg(DISTINCT selected_customfields::character varying, ',') || ',email '
|| 'FROM (
    SELECT
        elems ->> ''name'' AS column_name,
        elems -> ''value'' ->> 0 AS value,
         "customFieldValues",email
    FROM
        dl_get_response.gr_contacts,
        json_array_elements( "customFieldValues"::json) elems
) s
GROUP BY  "customFieldValues",s.email''' as q
FROM CTE
)

How to execute the string that is generated from the above CTE?

Below is the sample value in the column "customFieldValues(This is of TEXT datatype, The below example will convert it into a JSON type and will get each name and it's value from it.

[
{"value": ["product_101"], "values": ["product_101"], "type": "text", "valueType": "string", "name": "cat_1", "customFieldId": "ef", "fieldType": "text"}
,{"value": ["AXE"], "values": ["AXE"], "type": "text", "valueType": "string", "name": "cat_2", "customFieldId": "e3", "fieldType": "text"}
,{"value": ["General"], "values": ["General"], "type": "text", "valueType": "string", "name": "customer_group", "customFieldId": "ee", "fieldType": "text"}
]

The sample output of the above will be,

Cat_1(Column 1)          cat_2(column 2)     customer_group(column 3)
product_101              AXE                 General

So basically in each set i need the "name" data to be the column name and "value" to be that column value.the challenge is that if i give the query hardcoded it will work perfectly like below.But i need to specify each column name "MAX(value) FILTER (WHERE column_name = 'cat_1') AS cat_1_all"like this ,But the values in the "customFieldValues"column can be changed,So whenever a new column is added i need to change this script.So i thought of taking the column names dynamically as shown in the above code,So whatever columns is added it will automatically take the new columns and it's values and form the table structure.

And the topmost code is the one came to my mind,So i created a the whole query as a string variable and i need to execute that, that's what i was trying to do in the topmost code.

Hope i have made it clear, Will be very helpful if you can guide on this.

SELECT email,
MAX(value) FILTER (WHERE column_name = 'cat_1') AS cat_1_all,
MAX(value) FILTER (WHERE column_name = 'cat_2') AS cat_2_all,
MAX(value) FILTER (WHERE column_name = 'customer_group') AS customer_group
FROM (
    SELECT
        elems ->> 'name' AS column_name,
        elems -> 'value' ->> 0 AS value,
         "customFieldValues",email
    FROM
        dl_get_response.gr_contacts,
        json_array_elements( "customFieldValues"::json) elems
) s
GROUP BY  "customFieldValues",s.email
Sandeep
  • 671
  • 2
  • 7
  • 30
  • That query is quite muddled and complicated, and without a table definition and some test data I cannot fully understand what you want. Maybe you can come up with a simplified example that illustrates the problem. – Laurenz Albe Jul 17 '19 at 15:44
  • @LaurenzAlbe I have modified my original question and added more information to it.Can you please check and let me know if a suitable solution can be achieved on this? – Sandeep Jul 18 '19 at 09:26
  • Maybe using `query_to_xml` (as I have done [here](https://stackoverflow.com/a/56838029/330315)) or write your own [`query_to_jsonb`](https://blog.sql-workbench.eu/post/query-to-json/) –  Jul 18 '19 at 11:10
  • @a_horse_with_no_name Actually i want to execute the top most query,That is a dynamically created query and when that query is executed it will give the data in table structure and i need to insert that to a destination table. – Sandeep Jul 18 '19 at 13:09
  • @LaurenzAlbeAny suggestions on this,Any guidance will be of great help! – Sandeep Jul 30 '19 at 08:41

1 Answers1

1

Quoting the comments of a_horse_with_no_name,

Maybe using query_to_xml "How to search a specific value in all tables (PostgreSQL)?" or write your own query_to_jsonb – "https://blog.sql-workbench.eu/post/query-to-json/"resolved this. I used query to xml method and it worked out well.

Thanks a lot for the answers.

Sandeep
  • 671
  • 2
  • 7
  • 30