其中CLAUSE和NULL值

时间:2018-09-21 03:28:24

标签: sql sql-server

我有以下专栏

+---------+----------+----------+
| Account | Employee |   Org    |
+---------+----------+----------+
|     123 | ABC      | Gold     |
|     234 | PQR      | Silver   |
|     456 | XYZ      |          |
|     567 | MNQ      | Gold     |
|     714 | RPT      | Platinum |
|     819 | MKQ      | BRONZE   |
|     100 | LPA      | Tin      |
|     101 | QRT      |          |
|     104 | LMY      | Platinum |
+---------+----------+----------+

现在的目的是将所有拥有ORG的员工(如青铜或锡)过滤掉

直接与查询有关;

Select * from table 1 where Org NOT IN ('Bronze','Tin')

但是,这将过滤我不希望ORG为NULL的记录。
所以基本上上面的查询给了我;

+---------+----------+----------+
| Account | Employee |   Org    |
+---------+----------+----------+
|     123 | ABC      | Gold     |
|     234 | PQR      | Silver   |
|     567 | MNQ      | Gold     |
|     714 | RPT      | Platinum |
|     104 | LMY      | Platinum |
+---------+----------+----------+

在我想要的地方;

+---------+----------+----------+
| Account | Employee |   Org    |
+---------+----------+----------+
|     123 | ABC      | Gold     |
|     234 | PQR      | Silver   |
|     456 | XYZ      |          |
|     567 | MNQ      | Gold     |
|     714 | RPT      | Platinum |
|     101 | QRT      |          |
|     104 | LMY      | Platinum |
+---------+----------+----------+

我可以通过用case语句用某些值替换NULL然后过滤记录来获得此结果,但是我认为必须有更干净,更简便的方法来做到这一点?

我当前的查询;

Select * from (
 select ACCOUNT , EMPLOYEE , 
       CASE WHEN ORG IS NULL THEN 'RETAIN'
       ELSE ORG END AS EORG FROM table1 ) P
       WHERE P.EORG not in ('Bronze','Tin')

有更好的方法吗?

6 个答案:

答案 0 :(得分:3)

您可以将NULL添加到白名单:

SELECT *
FROM table1
WHERE Org NOT IN ('Bronze', 'Tin') OR Org IS NULL;

答案 1 :(得分:0)

与其他任何内容相比,任何为null的都将返回false,甚至另一个null。错误的结果一直持续到最高水平;你不能用NOT

这是错误的:

'X' = null

这也是错误的:

NOT ('X' = null)

这是错误的:

 null IN ('X', null)

这也是:

null NOT IN('x', null)

乍看起来似乎违反直觉,但这是规则。

只能专门测试某项是否为空
something IS NULL
something IS NOT NULL

因此,要么专门迎合null,要么在比较之前将其转换为实数:

Select * from table where column not in (...) or column is null

Select * from table where coalesce(column, 'x') not in (...) 

要使第二种形式起作用,无论您输入的是什么(我输入x),都不应出现在IN列表中(否则它是IN,因此将被过滤掉),也不应出现在数据中。首选第一种形式,因为如果使用合并,并非所有数据库都会在列上成功使用索引

要点,当在堆栈溢出中发布时,请为代码行添加4个空格作为前缀-然后,它将在一个灰色框中以等宽字体显示,并保留多个空格(您使用了引号,黄色框,否空格,会使内容难以阅读)

答案 2 :(得分:0)

这是由于IN operator的工作方式。在该页面上要格外注意...

  

subquery expression 返回的任何空值,使用IN或NOT IN将它们与 test_expression 进行比较,则返回UNKNOWN。将空值与IN或NOT IN一起使用会产生意外的结果。

尝试一下。

WHERE P.EORG <> 'Bronze' and P.EORG <> 'Tin'

答案 3 :(得分:0)

将条件放在case语句中:

Select * 
from table1 
where CASE WHEN Org IS NULL OR Org NOT IN ('Bronze','Tin')
           THEN 1
           ELSE 0
      END = 1

答案 4 :(得分:0)

您可以在查询中简单地使用ISNULL函数

选择* 从表1 ISNULL(Org,'')NOT IN('Bronze','Tin')哪里

答案 5 :(得分:-1)

尝试这样做。

SELECT * 
FROM   [dbo].[stockmaster] 
WHERE  openingweight NOT IN ( '10' ) OR openingweight IS NULL