如果值在下一列的列表设置值中NULL

时间:2019-04-16 09:41:27

标签: sql sql-server

我有一个庞大的SQL表,并且如果此列表中有几列(称为Field),则需要对其进行过滤:

AAA, BBB, CCC, DDD, EEE

在这种情况下,请将相应的value列设置为NULL。

让我给你一个示例表:

Field1  Value1  Field2  Value2 ...... Field10  Value10
  AAA     9A      AAA     9A            CCC       World    
  BBB     1       KKK     0    
  ZZZ     9       AAA     9A            CCC       42      
  CCC     7
  LLL     9       AAA     3             III       98     
  KKK     3       AAA     4    
  DDD     100     AAA     Hello         CCC       6  

Value10之前,并非所有字段值组合都被填充。但是,必须检查每个名为FieldXX的列中的列表项。如果单元格等于列表条目,则相应的值字段应设置为NULL。否则,值字段将保持不变。

对于这个特定问题,我很难找出正确的CASE陈述。我尝试了以下代码:

SELECT CAST(
             CASE 
                  WHEN Field* = AAA or BBB or CCC or DDD or EEE 
                     THEN Value* = 0
                  ELSE Value* = Value*
             END AS bit)
FROM dbo.Log

但是此查询完全失败,并且可能不是针对特定的字段值对。

预期产量

Field1  Value1  Field2  Value2 ...... Field10  Value10
  AAA     0       AAA     0            CCC       0    
  BBB     0       KKK     0    
  ZZZ     9       AAA     0            CCC       0      
  CCC     0
  LLL     9       AAA     0            III       98     
  KKK     3       AAA     0    
  DDD     0       AAA     0            CCC       0 

表名称为dbo.Log

4 个答案:

答案 0 :(得分:2)

如果我正确理解,您正在尝试根据FieldX数据更新ValueX列。 在这种情况下,您需要为每一列编写Case条件。

您可以直接编写以下10种情况条件

UPDATE A_LOG 
SET VALUE1 = CASE WHEN FIELD1 IN ('AAA','BBB','CCC','DDD','EEE' ) THEN 0 ELSE VALUE1 END,
VALUE2 = CASE WHEN FIELD2 IN ('AAA','BBB','CCC','DDD','EEE' ) THEN 0 ELSE VALUE2 END,
VALUE3 = CASE WHEN FIELD3 IN ('AAA','BBB','CCC','DDD','EEE' ) THEN 0 ELSE VALUE3 END
.
.
VALUE10 = CASE WHEN FIELD10 IN ('AAA','BBB','CCC','DDD','EEE' ) THEN 0 ELSE VALUE10 END

或者您可以使用如下所示的动态查询生成Update语句

DECLARE @IN VARCHAR(100)=' IN (''AAA'',''BBB'',''CCC'',''DDD'',''EEE'' )'
, @SQL VARCHAR(MAX) =  'UPDATE A_LOG SET '

SELECT @SQL = @SQL+  VAL FROM 
(
SELECT    COLUMN_NAME + ' = CASE WHEN FIELD'+ REPLACE(COLUMN_NAME,'VALUE','')
+ @IN+ ' THEN 0 ELSE '+ COLUMN_NAME + ' END,
' VAL
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'LOG'
AND COLUMN_NAME LIKE 'VALUE%'
)A

SELECT @SQL = SUBSTRING(@SQL,1,LEN(@SQL)-3)
SELECT @SQL

这将为您提供带有条件条件的每一列的更新语句。

答案 1 :(得分:1)

尝试一下:

    Declare @Table Table(Field1 varchar(10), Value1 varchar(10),  Field2 varchar(10),  Value2 varchar(10) ,Field10 varchar(10) , Value10 varchar(10))
    Declare @NewTable Table(Field1 varchar(10), Value1 varchar(10),  Field2 varchar(10),  Value2 varchar(10) ,Field10 varchar(10) , Value10 varchar(10))

    insert into @Table
    SELECT 'AAA','9A','AAA','9A','CCC','World' Union All
    SELECT 'BBB','1','KKK','0',NULL,NULL    Union All
    SELECT 'ZZZ','9','AAA','9A','CCC','42'   Union All    
    SELECT 'CCC','7',NULL,NULL,NULL,NULL Union All
    SELECT 'LLL','9','AAA','3','III','98' Union All
    SELECT 'KKK','3','AAA','4',NULL,NULL    Union All
    SELECT 'DDD','100','AAA','Hello','CCC','6' 


    INSERT into @NewTable
    Select Field1,CASE WHEN Field1 in ('AAA','BBB','CCC','DDD','EEE') THEN 0 else Value1 end As Value1
        ,Field2,CASE WHEN Field2 in ('AAA','BBB','CCC','DDD','EEE') THEN 0 else Value2 end As Value2
        ,Field10,CASE WHEN Field10 in ('AAA','BBB','CCC','DDD','EEE') THEN 0 else Value10 end As Value10
    from @Table 

    Select * from @NewTable

答案 2 :(得分:1)

Case语句不能以您编写的方式工作。您需要分别比较每个字段中的值并设置“值”列的值。

SELECT CAST(
             CASE 
                  WHEN Field1 = AAA or BBB or CCC or DDD or EEE 
                     THEN Value1 = 0                     
                  ELSE Value1
             END AS bit) Value1,
        CAST(
             CASE 
                  WHEN Field2 = AAA or BBB or CCC or DDD or EEE 
                     THEN Value2 = 0                     
                  ELSE Value2
             END AS bit) Value2,
        .    
        .
        .
        .
        <need to write separate case statement for each column which is to be compared>
FROM dbo.Log

答案 3 :(得分:1)

我敢肯定,您要尝试为CASE WHEN使用通配符不是有效的使用方式。

您可以使用变量创建一个SQL字符串,然后可以复制并执行该字符串-这样,如果您需要增加要检查的字段数,则只需更改代码的一部分即可:)< / p>

下面的代码创建SQL字符串,然后在控制台窗口中将其打印出来:

DECLARE @cnt INT = 1;
DECLARE @sql VARCHAR(MAX) = 'SELECT ';
WHILE @cnt <= 10
BEGIN 
DECLARE @COLUMN VARCHAR(MAX) = 'Field' + CAST(@cnt AS varchar(max))
DECLARE @VALUE VARCHAR(MAX) = 'Value' + CAST(@cnt AS varchar(max))
SET @sql = @sql + @COLUMN + ', CASE WHEN ' + @COLUMN + '= ''AAA'' OR '  + @COLUMN + '= ''BBB'' OR ' + @COLUMN + '= ''CCC'' OR ' + @COLUMN + '= ''DDD'' OR ' + @COLUMN + '= ''EEE'' THEN 0 ELSE ' + @VALUE + ' END AS ' + @VALUE;
IF @cnt != 10 
(SELECT @sql = @sql + ',')
SET @cnt = @cnt +1
END

SET @sql = @sql + ' INTO [dbo].[LogFilter] FROM [dbo].[Log]';
PRINT @sql;

下面的代码是打印出来的(我已经设置了样式,以便您可以轻松阅读并截断它,从而不会占用整个屏幕):)

SELECT 
  Field1, 
  CASE WHEN Field1= 'AAA' OR Field1= 'BBB' OR Field1= 'CCC' OR Field1= 'DDD' OR Field1= 'EEE'
  THEN 0 ELSE Value1 END AS Value1,
  Field2, 
  CASE WHEN Field2= 'AAA' OR Field2= 'BBB' OR Field2= 'CCC' OR Field2= 'DDD' OR Field2= 'EEE' 
  THEN 0 ELSE Value2 END AS Value2,
  Field3, 
  CASE WHEN Field3= 'AAA' OR Field3= 'BBB' OR Field3= 'CCC' OR Field3= 'DDD' OR Field3= 'EEE' 
  THEN 0 ELSE Value3 END AS Value3, 
  ...
  INTO [dbo].[LogFilter] FROM [dbo].[Log]

上面的SELECT INTO语句将过滤后的信息放入一个全新的表中:)