【发布时间】:2019-11-26 07:39:47
【问题描述】:
我有一个包含 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
【问题讨论】:
-
该查询相当混乱和复杂,没有表定义和一些测试数据,我无法完全理解您想要什么。也许你可以想出一个简单的例子来说明这个问题。
-
@LaurenzAlbe 我已经修改了我原来的问题并添加了更多信息。您能否检查一下并让我知道是否可以为此实现合适的解决方案?
-
也许使用
query_to_xml(就像我已经做过的here)或者写你自己的query_to_jsonb -
@a_horse_with_no_name 实际上我想执行最顶层的查询,这是一个动态创建的查询,当执行该查询时,它将提供表结构中的数据,我需要将其插入到目标表中.
-
@LaurenzAlbe对此有任何建议,任何指导都会有很大帮助!
标签: postgresql