在PostgreSQL中执行动态查询字符串

时间:2019-07-17 12:56:40

标签: postgresql

我有一个包含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

1 个答案:

答案 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方法,效果很好。

非常感谢您的回答。