查询值为空的单行的列名?

query column names for a single row where value is null?

我正在尝试 return 值为空的单个行的所有列名。之后我可以解析整行,但很好奇是否有我可以利用的功能。

我可以 return 包含键值对的 JSON 对象,其中值为 not null 使用 row_to_json()json_strip_nulls 其中条件引用单个唯一行:

SELECT json_strip_nulls(row_to_json(t))
   FROM table t where t.id = 123

是否有函数或简单的方法来完成此操作的逆过程,return将所有键(列名)设为空值?

您需要一个主键或唯一列。在示例中 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)    

keyvalue 是函数返回的默认列 jsonb_each_text(). 请参阅文档中的 JSON Functions and Operators

实际上 JSON 方法可能有效。首先使用 row_ro_json() 将行转换为 JSON 对象。然后使用 json_each_text() 将 JSON 个对象扩展回一个集合。您现在可以筛选 NULL 值并使用聚合来获取包含 NULL.

的列

我不知道你想要什么输出格式。 json_object_agg() 是您的 json_strip_nulls()/row_to_json() 方法的 "complement"。但您可能还需要一个 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;

db<>fiddle