【问题标题】:Delete many columns with null删除许多带有 null 的列
【发布时间】:2019-08-05 00:05:12
【问题描述】:

我有一张有 34 列的表格。 前 4 列形成主键(因此它们中没有空值),其余 30 列中的数据也为空值。 我希望删除其他 30 列为空的所有行。 一种方法是 -

delete from my_table
where column_30 is null
and columns_29 is null
and column_28 is null
and column_27 is null
...
...
...

有没有什么简单的方法可以在不提及所有 30 个列名的情况下做到这一点?

【问题讨论】:

  • 并非如此。大约现在,您应该问自己这张桌子是否设计正确。当您刚刚给我们提供模糊的列名时,当然不可能说,但我怀疑任何具有大量列的表,尤其是当所有非 PK 列都可以为空时。
  • 它是一个输入表,是从 csv 文件直接转储的,因此它没有约束和检查

标签: sql sql-server tsql null where-clause


【解决方案1】:

不,那是不可能的。您可以稍微缩短代码,但支付penalty in sargability - 使用coalesce

delete from my_table
where coalesce(column_30, column_29, column_28.....) is null

正如 Damien 在他的评论中所写 - 这只有在所有列都是兼容类型时才有效,这意味着 SQL Server 可以在它们之间隐式转换。

【讨论】:

  • 我认为这假设所有这些列都是兼容的类型。如果其中一个是 say 和 int,其余的是 varchar(something),则此查询将阻塞第一个(显然非空)字符串,该字符串无法转换为 int
【解决方案2】:

另一种方法。 (假设所有列的数据类型相同)

delete t 
from   my_table t 
where  (select top 1 1 as col 
        from   (values  (T.column_30), 
                        (T.columns_29), 
                        (T.columns_28 ), 
                        (T.columns_27 )) v(x) 
        where  x is null) = 1 

【讨论】:

    【解决方案3】:

    coalesce 接收表达式列表并返回第一个非空值,或者如果它们都是空值,则返回空值,因此您可以将其用作某种速记:

    DELETE FROM mytable
    WHERE  COALESCE(column_30, column_29, column_28, ...) IS NULL
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 2011-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多