postgresql Postgres -处理空元素集

cgvd09ve  于 2023-04-20  发布在  PostgreSQL
关注(0)|答案(2)|浏览(134)

假设我有一个表,它有一个json类型的多值列,其中包含数组。所以为了规范化关系,可以这样做:

select 
    id,  
    description,
    json_array_elements(letters)
  from
  (
    values
    (1, 'good', '["a","b", "c"]'::json),
    (2, 'bad', '[]'::json)
  ) as aTable(id,description,letters);

(即用型示例here
这里的问题是id为2的行没有列出,因为数组是空的(或null)。
所以我确实想知道我必须做什么样的事情,才能得到与模拟的那一行|默认值|硬编码值......例如,我尝试了以下操作:

select 
    id,  
    description,
      CASE 
        WHEN json_array_length(letters) = 0 THEN '"x"'::json
        ELSE json_array_elements(letters)
      END 
  from
  (
    values
    (1, 'good', '["a","b", "c"]'::json),
    (2, 'bad', '[]'::json)
  ) as aTable(id,description,letters)

(RTR示例here
postgres声明这是不可能的

ERROR:  set-returning functions are not allowed in CASE
LINE 6:         ELSE json_array_elements(letters)
                     ^
HINT:  You might be able to move the set-returning function into a LATERAL FROM item.

我试过提示,但也没有结果...

select 
    id, 
    description, 
    l.letter
  from
  (
    values
    (1, 'good', '["a","b", "c"]'::json),
    (2, 'bad', '[]'::json)
  ) as aTable(id,description,letters)
  CROSS JOIN LATERAL (
    SELECT 
        CASE 
            WHEN json_array_length(letters) = 0 THEN '"x"'::json
            ELSE json_array_elements(letters)
        END
  ) as l(letter)

所以很有可能我没有得到提示…
我想知道是否有人可以帮助我。
谢谢
维克多

esyap4oy

esyap4oy1#

这可以使用带有条件on trueleft join来完成

with cte(id,description,letters) as (
  values
    (1, 'good', '["a","b", "c"]'::json),
    (2, 'bad', '[]'::json)
)
select id,description, COALESCE(l.value::text, 'x') as letter
from cte
left join json_array_elements_text(letters) l on true

它也可以使用:

with cte(id,description,letters) as (
  values
    (1, 'good', '["a","b", "c"]'::json),
    (2, 'bad', '[]'::json)
)
select id,description, COALESCE(l.value::text, 'x') as letter
from cte,
json_array_elements_text(case when letters::text = '[]' then '[null]'::json else letters end) l;

json_array_elements_text('[null]')返回null,
json_array_elements_text('[]')不返回任何内容
Demo here

iq0todco

iq0todco2#

另一种方法是用“x”替换json数组:

select 
    id,  
    description,
    json_array_elements(CASE WHEN json_array_length(letters) = 0 THEN '["x"]'::json ELSE letters END)
from
  (
    values
    (1, 'good', '["a","b", "c"]'::json),
    (2, 'bad', '[]'::json)
  ) as aTable(id,description,letters);

相关问题