设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 创业者 数据 手机
当前位置: 首页 > 站长学院 > MySql教程 > 正文

搞清这些陷阱,NULL和三值逻辑再也不会作妖(3)

发布时间:2019-11-07 20:19 所属栏目:115 来源:youzhibing2904
导读:-- 添加 3 个条件:年龄是20 岁,或者不是20 岁,或者年龄未知 --添加3个条件:年龄是20岁,或者不是20岁,或者年龄未知 SELECT*FROMt_student WHEREage=20 ORage20 ORageISNULL; CASE 表达式和 NULL。简单 CASE 表

-- 添加 3 个条件:年龄是20 岁,或者不是20 岁,或者年龄未知

  1. -- 添加 3 个条件:年龄是20 岁,或者不是20 岁,或者年龄未知 
  2. SELECT * FROM t_student 
  3. WHERE age = 20  
  4.     OR age <> 20 
  5.     OR age IS NULL; 

CASE 表达式和 NULL。简单 CASE 表达式如下:

  1. CASE col_1 
  2.     WHEN = 1 THEN 'o' 
  3.     WHEN NULL THEN 'x' 
  4. END 

这个 CASE 表达式一定不会返回 ×。这是因为,第二个 WHEN 子句是 col_1 = NULL 的缩写形式。正如我们所知,这个式子的逻辑值永远是 unknown ,而且 CASE 表达式的判断方法与 WHERE 子句一样,只认可逻辑值为 true 的条件。正确的写法是像下面这样使用搜索 CASE 表达式:

  1. CASE WHEN col_1 = 1 THEN 'o' 
  2.     WHEN col_1 IS NULL THEN 'x' 
  3. END 

NOT IN 和 NOT EXISTS 并非等价

我们在对 SQL 语句进行性能优化时,经常用到的一个技巧是将 IN 改写成 EXISTS ,这是等价改写,并没有什么问题。但是,将 NOT IN 改写成 NOT EXISTS 时,结果未必一样。

我们来看个例子,我们有如下两张表:t_student_A 和 t_student_B,分别表示 A 班学生与 B 班学生。

  1. DROP TABLE IF EXISTS t_student_A; 
  2. CREATE TABLE t_student_A ( 
  3.     id INT(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', 
  4.     name VARCHAR(50) NOT NULL COMMENT '名称', 
  5.     age INT(3) COMMENT '年龄', 
  6.     city VARCHAR(50) NOT NULL COMMENT '城市', 
  7.     remark VARCHAR(500) NOT NULL DEFAULT '' COMMENT '备注', 
  8.     primary key(id) 
  9. ) COMMENT '学生信息'; 
  10.  
  11. INSERT INTO t_student_A(name, age, city) 
  12. VALUE 
  13. ('zhangsan', 25,'深圳市'),('wangwu', 60, '广州市'), 
  14. ('bruce', 32, '北京市'),('yzb', NULL, '深圳市'), 
  15. ('boss', 43, '深圳市'); 
  16.  
  17. DROP TABLE IF EXISTS t_student_B; 
  18. CREATE TABLE t_student_B ( 
  19.     id INT(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', 
  20.     name VARCHAR(50) NOT NULL COMMENT '名称', 
  21.     age INT(3) COMMENT '年龄', 
  22.     city VARCHAR(50) NOT NULL COMMENT '城市', 
  23.     remark VARCHAR(500) NOT NULL DEFAULT '' COMMENT '备注', 
  24.     primary key(id) 
  25. ) COMMENT '学生信息'; 
  26.  
  27. INSERT INTO t_student_B(name, age, city) 
  28. VALUE 
  29. ('马化腾', 45, '深圳市'),('马三', 25, '深圳市'), 
  30. ('马云', 43, '杭州市'),('李彦宏', 41, '深圳市'), 
  31. ('年轻人', 25, '深圳市'); 
  32.  
  33. SELECT * FROM t_student_A; 
  34. SELECT * FROM t_student_B; 

需求:查询与 A 班住在深圳的学生年龄不同的 B 班学生,也就说查询出 :马化腾 和 李彦宏,这个 SQL 该如何写,像这样?

  1. -- 查询与 A  班住在深圳的学生年龄不同的 B 班学生 ? 
  2. SELECT * FROM t_student_B 
  3. WHERE age NOT IN ( 
  4.     SELECT age FROM t_student_A  
  5.     WHERE city = '深圳市' 
  6. ); 

我们来看下执行结果:

搞清这些陷阱,NULL和三值逻辑再也不会作妖

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读