【问题标题】:How to delete rows where most columns are empty in postgresql?如何删除postgresql中大多数列为空的行?
【发布时间】:2022-07-18 21:26:30
【问题描述】:

我是SQL新手,如果这个问题很愚蠢,请原谅。

我有一个有 800 列的表。我想删除 > 400 列为空的所有行。我该怎么做?

【问题讨论】:

  • 这是一个类似的答案,但适用于 Sql Server(不是 postgres):stackoverflow.com/a/58320834/1260204。我不熟悉 postgres 但是 如果您可以查询架构然后使用它来创建带有 sum 子句(每列 1 个)的动态语句,如果值为 null,则使用 1,否则使用 0那么如果总和大于 400 删除它应该是可能的,而不必对所有列名进行硬编码。

标签: sql postgresql


【解决方案1】:

您可以尝试将整行加上非空 const 转换为类似 JSON 的字符串,并计算 '":null,' 子字符串的数量。我假设id 是一个键,所以这将为id 返回一些NULL

create table foo (
    id int,
    c1 int,
    c2 int
);

insert into foo 
  values
  (1,10, 5),
  (2,null,15)
;

select id, (char_length(c) - char_length(REPLACE(c, '":null,', ''))) / char_length('":null,') cnt
from (
  select  id, json_agg(t)::text c
  from (
    select *, 1
    from foo
  ) t
  group by id
) t
order by id

返回

id  cnt
1   0
2   1

【讨论】:

    【解决方案2】:

    一种方法是使用num_nulls()函数:

    delete from wide_table
    where num_nulls(col1, col2, col3, col4, ...., col800) > 400;
    

    由于您只需要写入一次列数,因此这应该是最简单的方法。通常图形 SQL 客户端会帮助您自动完成列名,这样您就不必手动输入它们。

    如果您不想输入列名(或者您的 SQL 客户端不支持),您可以使用一些 JSON 转换来获取非空值的数量:

    select *
    from wide_table wt
    where jsonb_array_length(jsonb_path_query_array(jsonb_strip_nulls(to_jsonb(wt)), '$.*')) <= 400
    

    jsonb_strip_nulls(to_jsonb(wt)) 将生成一个 JSON 值,其中删除了所有键(=列名),其中值(=列值)为 NULL。所以它只包含非空值。然后jsonb_path_query_array(..., '$.*') 构建一个包含这些非空值的数组,jsonb_array_length 计算数字。

    请注意,需要反转条件,因为jsonb_array_length() 返回-null 值的数量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-21
      • 1970-01-01
      • 2018-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多