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

时间:2019-01-08 23:34:40

标签: sql postgresql columnname

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

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

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

有没有一种函数或简单的方法可以完成相反的操作,返回所有带有空值的键(列名)?

2 个答案:

答案 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)    

keyvalue是函数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;

db<>fiddle