我有一个包含JSON值的表,并且我使用以下查询对其进行了操作,如果我分别指定每列,则该查询将正常运行,而不是我希望它是动态的,因此如果我添加了任何列添加到JSON字符串中,那么它将自动采用相应的列。
那么我如何在PostgreSQL中执行下面生成的动态查询?
曾尝试使用EXECUTE,但在SELECT附近显示语法错误。
任何建议都会有很大帮助。
-- 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
)
如何执行从上述CTE生成的字符串?
下面是“ customFieldValues(这是TEXT数据类型)列中的示例值。下面的示例将其转换为JSON类型,并从中获取每个名称及其值。
[
{"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"}
]
以上示例输出为
Cat_1(Column 1) cat_2(column 2) customer_group(column 3)
product_101 AXE General
因此,基本上,在每个集合中,我都需要“名称”数据作为列名,“值”作为该列值。挑战在于,如果我对查询进行硬编码,它将可以像下面那样完美地工作。但是我需要像这样指定每个列名称“ MAX(value)FILTER(WHERE column_name ='cat_1') AS cat_1_all”,但是“ customFieldValues”列中的值可以更改,因此每当有新列时添加后,我需要更改此脚本。因此,我想到了如上述代码中所示动态获取列名的方法,因此,无论添加什么列,它都会自动获取新列及其值并形成表结构。
最重要的代码就是我想到的代码,所以我创建了一个完整的查询作为字符串变量,我需要执行该操作,这就是我试图在最高级的代码中执行的操作。
希望我已明确表示,如果您能对此进行指导,将会非常有帮助。
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
答案 0 :(得分:1)
引用a_horse_with_no_name的注释,
也许使用query_to_xml“ How to search a specific value in all tables (PostgreSQL)?” 或编写自己的query_to_jsonb –“ https://blog.sql-workbench.eu/post/query-to-json/”解决了此问题。我将查询用于xml方法,效果很好。
非常感谢您的回答。