提取表中包含少于 x NULL 的行

sql*_*wie 4 sql-server query isnull

我正在使用包含大量 NULL 的 SQL Server 数据库。为了分析我的数据,我想提取数据库表的所有行,包括少于 x 个 NULL 标记(例如 x=2)。

我的数据库类似于这个结构:

 c1        c2      c3      c4        c5        
-----------------------------------------------------
2          3       NULL    1         2
2          NULL    NULL    1         2
2          3       NULL    NULL      2
NULL       3       NULL    1         NULL
2          3       NULL    1         2
Run Code Online (Sandbox Code Playgroud)

我尝试了查询,它没有返回错误,但没有选择任何行:

SELECT * FROM test123 
WHERE ((ISNULL(c1,1) + ISNULL(c2,1) + ISNULL(c3,1) + ISNULL(c4,1) + ISNULL(c5,1)) < 2);
Run Code Online (Sandbox Code Playgroud)

我希望此查询返回第一行和第五行,但结果包含 0 行。


我无法测试以下代码,因为我没有在数据库上写入的权限,但这里有一个(伪)代码,用于创建像我这样的表:

CREATE TABLE test123(
    c1 float,
    c2 float,
    c3 float,
    c4 float,
    c5 float
) GO
INSERT test123(c1,c2,c3,c4,c5)
VALUES (2,3,NULL,1,2),
       (2,NULL,NULL,1,2),
       (2,3,NULL,NULL,2),
       (NULL,3,NULL,1,NULL),
       (2,3,NULL,1,2);
Run Code Online (Sandbox Code Playgroud)

Aar*_*and 8

在当前数据库中创建表的权限不应妨碍您创建可以使用的表。您可以创建一个#temp 表:

CREATE TABLE #test123(
    c1 float,
    c2 float,
    c3 float,
    c4 float,
    c5 float
);

INSERT #test123(c1,c2,c3,c4,c5);
VALUES (2,3,NULL,1,2),
       (2,NULL,NULL,1,2),
       (2,3,NULL,NULL,2),
       (NULL,3,NULL,1,NULL),
       (2,3,NULL,1,2);
Run Code Online (Sandbox Code Playgroud)

要查看为什么ISNULL在这里无效,请运行以下查询:

SELECT ISNULL(c1,1), ISNULL(c2,1), ISNULL(c3,1), ISNULL(c4,1), ISNULL(c5,1)
  FROM #test123;
Run Code Online (Sandbox Code Playgroud)

您已为每一行中的每一列指定了一个值。因此,现在您正在评估膨胀值的 SUM,并错误地评估实际值的属性(当其中一个值为负时会发生什么?),而不是评估 COUNT 为 NULL 或 NOT NULL 的值。

这是更多的代码,但解决这个问题的简单方法是:

SELECT * FROM #test123
  WHERE CASE WHEN c1 IS NULL THEN 1 ELSE 0 END
      + CASE WHEN c2 IS NULL THEN 1 ELSE 0 END
      + CASE WHEN c3 IS NULL THEN 1 ELSE 0 END
      + CASE WHEN c4 IS NULL THEN 1 ELSE 0 END
      + CASE WHEN c5 IS NULL THEN 1 ELSE 0 END < 2;
Run Code Online (Sandbox Code Playgroud)


Jos*_*ell 7

您应该使用这样的 case 语句:

SELECT * 
FROM test123 
WHERE (
    (CASE WHEN C1 IS NULL THEN 1 ELSE 0 END + 
     CASE WHEN C2 IS NULL THEN 1 ELSE 0 END + 
     CASE WHEN C3 IS NULL THEN 1 ELSE 0 END + 
     CASE WHEN C4 IS NULL THEN 1 ELSE 0 END + 
     CASE WHEN C5 IS NULL THEN 1 ELSE 0 END) 
    < 2);
Run Code Online (Sandbox Code Playgroud)

ISNULL方法在值不是 时返回您的实际值NULL,这会将所有行推到 2 标记之上。