如果STRING_AGG不为空或NULL,则将CONCAT / CONCAT_WS与STRING_AGG一起使用字符串来结果?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如果STRING_AGG不为空或NULL,则将CONCAT / CONCAT_WS与STRING_AGG一起使用字符串来结果?相关的知识,希望对你有一定的参考价值。
我有像这样存储在data列中的JSONB数据:
...,
"cars": [
{ "name":"Ford"},
{ "name":"BMW" },
{ "name":"Fiat"}
],
...
还有其他几个属性,它们存储更多的对象数组,但是为了简化我的问题,我只想提及一个。
首先,我想看看是否可以将每个对象的所有名称属性收集到一个字段中。我找到了following question并接受了答案,这使我实现了与以下目标类似的最初目标:
SELECT
id
, STRING_AGG(car->>'name', ', ')
FROM
autos,
json_array_elements(autos.data->'cars') as car
GROUP BY 1
这将产生一个看起来像这样的字段:
Ford, BMW, Fiat
我的最终目标是能够将所有其他STRING_AGG对象属性连接到一个字段,并在每个字段中都进行简短描述,但是仅当STRING_AGG的结果为NOT EMPTY和NOT NULL时(在我的情况下,最重要的是NOT EMPTY('')。例如,它应如下所示:
...//Cars: Ford, BMW, Fiat //Years: 1991, 1992, 1993 //Model: Mustang, Prius, Chevelle // ... etc., etc.
我曾尝试使用CONCAT和CONCAT_WS,并尝试利用NULLIF,但不确定如何实现所需的内容。特别是,如果有可能在每个STRING_AGG结果前添加一个描述字符串。你能帮忙吗?
Click: step-by-step demo:db<>fiddle
WITH autos AS (
SELECT '{"cars": [{"name": "BMW", "year": 1991}, {"name": "Ford", "model": "Mustang"}, {"name": "Fiat"}, {"name": "VW", "model": "Golf", "year": 2000}, {"name": "VW", "model": ""}]}'::jsonb as data
)
SELECT
'Cars: ' || STRING_AGG(NULLIF(car ->> 'name', ''), ',') || ' // '
'Years: ' || STRING_AGG(NULLIF(car ->> 'year', ''), ',') || ' // '
'Models: ' || STRING_AGG(NULLIF(car ->> 'model', ''), ',')
FROM autos,
jsonb_array_elements(data->'cars') as car
使用此数据集:
{
"cars": [
{
"name": "BMW",
"year": 1991
},
{
"name": "Ford",
"model": "Mustang"
},
{
"name": "Fiat"
},
{
"name": "VW",
"year": 2000,
"model": "Golf"
},
{
"name": "VW",
"model": ""
}
]
}
您可以看到:model
没有== null
(BMW
),year
没有Ford
,Fiat
完全没有数据,VW Golf
的所有属性,第二个model
为空VW
。
首先获取所有数据的表:
SELECT
car ->> 'name' as name,
car ->> 'year' as year,
car ->> 'model' as model
FROM autos,
jsonb_array_elements(data->'cars') as car
您已经使用了jsonb_array_elements()
函数,该函数扩展了JSON数组。 ->>
运算符将属性值(在这种情况下为每个数组元素)指定为text
。
现在,您可以使用model
将空值(在这种情况下,将第二个VW
的NULL
标准化为NULLIF()
)。如果为NULL
,则可以为空:
NULLIF(myvalue, '')
这将导致您:
SELECT
NULLIF(car ->> 'name', '') as name,
NULLIF(car ->> 'year', '') as year,
NULLIF(car ->> 'model', '') as model
FROM autos,
jsonb_array_elements(data->'cars') as car
现在您已经没有空值,但是有许多NULL
值。
现在,您可以使用STRING_AGG()
汇总所有值。提示是,STRING_AGG()
自动忽略NULL
值,因此您不必犹豫。
SELECT
STRING_AGG(NULLIF(car ->> 'name', ''), ',') as names,
STRING_AGG(NULLIF(car ->> 'year', ''), ',') as years,
STRING_AGG(NULLIF(car ->> 'model', ''), ',') as models
FROM autos,
jsonb_array_elements(data->'cars') as car
现在,您只有三列和一行。每个值都汇总到字符串中。
最后,您要将它们链接成一个字符串。为此,您可以使用CONCAT()
或运算符||
:
SELECT
'Cars: ' || STRING_AGG(NULLIF(car ->> 'name', ''), ',') || ' // '
'Years: ' || STRING_AGG(NULLIF(car ->> 'year', ''), ',') || ' // '
'Models: ' || STRING_AGG(NULLIF(car ->> 'model', ''), ',')
FROM autos,
jsonb_array_elements(data->'cars') as car
以上是关于如果STRING_AGG不为空或NULL,则将CONCAT / CONCAT_WS与STRING_AGG一起使用字符串来结果?的主要内容,如果未能解决你的问题,请参考以下文章