【问题标题】:determine if any values are null, if true then false, else true确定是否有任何值为空,如果为真则为假,否则为真
【发布时间】:2011-05-24 20:04:12
【问题描述】:

我目前有一个 select 语句,它检查几列以查看它们是否有数据。如果其中任何一个为空,那么我希望将其设置为假。如果它们都不为空,那么我希望将其设置为真。这是我目前拥有的:

select
cast(
        case when ChangeOrderNumber is null then 0 else 1 end *
        case when ClientName is null then 0 else 1 end *
        case when QuoteNumber  is null then 0 else 1 end *
        case when ClientNumber is null then 0 else 1 end *
        case when ServiceLine is null then 0 else 1 end *
        case when ServiceLineCode is null then 0 else 1 end *
        case when GroupLeader is null then 0 else 1 end *
        case when CreatedBy is null then 0 else 1 end *
        case when PTWCompletionDate is null then 0 else 1 end *
        case when BudgetedHours is null then 0 else 1 end *
        case when BudgetDollars is null then 0 else 1 end *
        case when InternalDeadlineDate is null then 0 else 1 end *
        case when ProjectDescription is null then 0 else 1 end *
        case when Sales is null then 0 else 1 end *
        case when Coop is null then 0 else 1 end *
        case when PassThrough is null then 0 else 1 end *
        case when POStatus is null then 0 else 1 end *
        case when PONumber is null then 0 else 1 end as bit
    ) 
    as Flag
from t

现在,该代码有效,但有点冗长,我想知道是否有人知道更好的方法来做到这一点。请注意,有几种数据类型被检查。

更多细节: 此代码位于正在处理变更单的应用程序中查看的视图中。在处理变更单之前,它必须通过一些数据质量检查。此视图显示任何必需的数据是否为空。

【问题讨论】:

  • 来吧,大卫......你不知道该怎么做吗:P

标签: sql-server tsql sql-server-2008


【解决方案1】:

只需将它们相加,因为 NULL + "something" 始终为 NULL ...

CREATE TABLE #test(column1 int,column2 varchar(4),column3 float)

INSERT #test VALUES(2,'2',2)
INSERT #test VALUES(0,'1',0)
INSERT #test VALUES(null,'1',0)
INSERT #test VALUES(1,null,0)
INSERT #test VALUES(0,'1',null)
INSERT #test VALUES(null,null,null)

SELECT CASE 
WHEN column1 + column2 + column3 is NULL THEN 0 ELSE 1 END, *
FROM #test

来自我 3 年前创建的 post...

请记住,如果您的字符不是数字,则必须将其转换为 varchar ...

INSERT #test VALUES(0,'abc',null)

这里是转换,不需要转换varchar列

SELECT CASE WHEN CONVERT(VARCHAR(100),column1) 
            + column2 
            +CONVERT(VARCHAR(100),column3)  is NULL THEN 0 ELSE 1 END,*
 FROM #test

【讨论】:

  • 与添加类似,您也可以使用按位与运算符 (&) 'SELECT CASE WHEN (4 & 5 & null) > 0 THEN 1 ELSE 0 END'
  • 正如我在最后一行中指出的那样......keep in mind that if you have characters that are not numbers that you have to convert to varchar
  • @SQLMenace,就是这样,varchars 确实有非数字字符,所以转换失败
  • 在这种情况下,将所有内容都转换为 varchar
  • @SQLMenace,那么它也一样长/血腥
【解决方案2】:

我想我可能会采用这个解决方案,除非有人提出更好的解决方案,受@Alireza 的启发:

cast(
        case when (ChangeOrderNumber is null  or
        a.ClientName is null  or
        a.QuoteNumber  is null  or
        ClientNumber is null  or
        ServiceLine is null  or
        ServiceLineCode is null  or
        GroupLeader is null  or
        CreatedBy is null  or
        PTWCompletionDate is null  or
        BudgetedHours is null  or
        BudgetDollars is null  or
        InternalDeadlineDate is null  or
        ProjectDescription is null  or
        Sales is null  or
        Coop is null  or
        PassThrough is null  or
        POStatus is null  or
        PONumber is null) then 'false' else 'true'
        end as bit) as Flag

【讨论】:

    【解决方案3】:

    请使用IIF()(需要是sql server 2012或更高版本)我真的推荐:

    IIF(column1 is null, '0', '1')
    

    【讨论】:

      【解决方案4】:

      这个呢?

      select not(a is null or b is null or ...)
      

      【讨论】:

        【解决方案5】:

        你可以颠倒逻辑。

        SELECT
            CASE WHEN ChangeOrderNumber IS NOT NULL
                    AND ClientName IS NOT NULL
                    AND QuoteNumber IS NOT NULL
                    ....
                THEN 1
                ELSE 0
            END [Flag]
        FROM t
        

        【讨论】:

          【解决方案6】:

          创建一个 HasValue 函数,该函数接受一个 sql_variant 并返回一个位。然后在 SELECT 子句中使用按位与。

          CREATE FUNCTION dbo.HasValue(@value sql_variant) RETURNS bit
          AS
          BEGIN
              RETURN (SELECT COUNT(@value))
          END
          
          GO
          
          SELECT dbo.HasValue(ChangeOrderNumber)
              & dbo.HasValue(ClientName)
              & dbo.HasValue(QuoteNumber)
              ...
              as [Flag]
          FROM t
          

          【讨论】:

          • 有意思,我去看看性能怎么样
          【解决方案7】:

          或者这个:

           declare @test1 char(1)
           declare @test2 char(1)
           declare @outbit bit
          
           set @test1 = NULL
           set @test2 = 'some value'
           set @outbit = 'True'
          
          
           select @test1
           select @test2
          
           If @test1 + @test2 IS NULL set @outbit = 'False'
           Select @outbit
          

          【讨论】:

          • 你只测试相同的数据类型,我的有多种数据类型。如果 char 包含任何非数字字符,则将 int 添加到 char 将失败
          【解决方案8】:

          简单得多——只需使用COALESCE 函数,它返回第一个非空列中的值。

          SELECT Flag = CASE 
              WHEN COALESCE (column1, column2, column3, ...) IS NULL THEN 0
              ELSE 1
             END
          FROM MyTable
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-02-20
            • 1970-01-01
            • 2021-10-15
            • 2016-05-03
            • 2014-10-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多