2011-05-24 17 views
8

Actualmente tengo una declaración de selección que verifica varias columnas para ver si tienen datos. si alguno de ellos es nulo, entonces quiero un bit establecido en falso. si ninguno de ellos es nulo, entonces quiero un poco establecido en verdadero. Esto es lo que tengo actualmente:determine si los valores son nulos, si son verdaderos y luego son falsos, de lo contrario son verdaderos

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 

ahora, funciona ese código, pero es un poco largo, me preguntaba si alguien sabía de una mejor manera de hacer esto. tenga en cuenta que se están verificando varios tipos de datos.

más detalles: este código está en una vista que se está mirando en una aplicación para procesar órdenes de cambio. antes de que se pueda procesar una orden de cambio, debe cumplir con algunos controles de calidad de datos. esta vista muestra si alguno de los datos requeridos es nulo.

+0

Vamos David ... ¿no sabe cómo hacer esto: P – SQLMenace

Respuesta

5

Creo que podría ir con esta solución a menos que alguien se le ocurre una mejor, inspirado en @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 
2

¿Qué hay de este?

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

O esto:

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 
+0

que' Solo estoy probando el mismo tipo de datos, el mío tiene múltiples tipos de datos. agregar un int a un char fallará si el char tiene caracteres no numéricos – DForck42

11

Sólo sumarlos ya NULL + "algo" siempre es 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 

de un post Me creado hace más de 3 años. ..

Tenga en cuenta que si tiene caracteres que no son números que debe convertir a varchar ...

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

Aquí es la conversión, sin necesidad de convertir las columnas varchar

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

Similar a agregar también se puede usar el operador bit a bit (&) 'SELECCIONAR CASO CUANDO (4 & 5 & null)> 0 THEN 1 ELSE 0 END ' – EBarr

+0

como indiqué en la última línea ...'tenga en cuenta que si tiene caracteres que no son números que tiene que convertir a varchar' – SQLMenace

+0

@SQLMenace, eso es lo que pasa, los varcars DO tienen caracteres no numéricos, por lo que falla en la conversión – DForck42

2

Se podría invertir la lógica.

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 
1

crear una función que toma HasValue en un sql_variant y devuelve un poco. Luego use AND a nivel de bit en su cláusula 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 
+0

interesante, tendré que mirar y ver cómo es el rendimiento – DForck42

0

Mucho más simple - sólo tiene que utilizar la función COALESCE, que devuelve el valor en la primera columna no nulo.

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

Utilice IIF() (necesito estar SQL Server 2012 o posterior) Realmente recomiendo:

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