我正在尝试为单行返回所有列名,其中值为null。之后,我可以解析整行,但很好奇是否有可以利用的功能。
我可以使用row_to_json()
和json_strip_nulls
返回一个包含键值对的JSON对象,其中值 not 为空,其中条件引用单个唯一行:
SELECT json_strip_nulls(row_to_json(t))
FROM table t where t.id = 123
有没有一种函数或简单的方法可以完成相反的操作,返回所有带有空值的键(列名)?
答案 0 :(得分:1)
您需要一个主键或唯一列。在示例中,id
是唯一的:
with my_table(id, col1, col2, col3) as (
values
(1, 'a', 'b', 'c'),
(2, 'a', null, null),
(3, null, 'b', 'c')
)
select id, array_agg(key) as null_columns
from my_table t
cross join jsonb_each_text(to_jsonb(t))
where value is null
group by id
id | null_columns
----+--------------
2 | {col2,col3}
3 | {col1}
(2 rows)
key
和value
是函数jsonb_each_text().
返回的默认列。请参见文档中的JSON Functions and Operators。
答案 1 :(得分:0)
实际上,JSON方法可能有效。首先使用row_ro_json()
将行转换为JSON对象。然后使用json_each_text()
将JSON对象扩展回一个集合。现在,您可以过滤NULL
个值,并使用聚合来获取包含NULL
的列。
我不知道您想要什么输出格式。 json_object_agg()
是您的json_strip_nulls()
/ row_to_json()
方法的“补充”。但是您可能还需要JSON数组(json_agg
),仅数组(array_agg()
)或逗号分隔的字符串列表(string_agg()
)。
SELECT json_object_agg(jet.k, jet.v),
json_agg(jet.k),
array_agg(jet.k),
string_agg(jet.k, ',')
FROM elbat t
CROSS JOIN LATERAL row_to_json(t) rtj(j)
CROSS JOIN LATERAL json_each_text(rtj.j) jet(k, v)
WHERE jet.v IS NULL
GROUP BY rtj.j::text;