在sql语句中出现exists关键字的时候,它先会对外表进行循环查询并且查询都会查看exists条件语句是否符合条件。当exists里的条件语句能够返回记录行时,条件就为真,就会返回当前数据。反之如果exists里的条件语句不能返回记录行,则当前循环到的这条数据就会被丢弃。exists的条件就是一个过滤条件,当能返回结果集则为true,不能返回结果集则为false;
如下:
select * from user where exists (select 1);Code language: JavaScript (javascript)
对user表的记录逐条取出,由于子条件中的select 1永远能返回记录行,那么user表的所有记录都将被加入结果集,所以与 select * from user;是一样的。
又如下:
select * from user where exists (select * from user where userId = 0);Code language: JavaScript (javascript)
可以知道对user表进行loop时,检查条件语句(select * from user where userId = 0),由于userId永远不为0,所以条件语句永远返回空集,条件永远为false,那么user表的所有记录都将被丢弃。
not exists与exists相反,也就是当exists条件有结果集返回时,loop到的记录将被丢弃,否则将loop到的记录加入结果集。
总的来说,如果A表有n条记录,那么exists查询就是将这n条记录逐条取出,然后判断n遍exists条件
select * from person p where exists(select * from student s where s.personid = p.id);Code language: JavaScript (javascript)
mysql> select * from person p where exists(select * from student s where s.personid = p.id);
+----+------+
| id | name |
+----+------+
| 1 | 张飞 |
| 2 | 关羽 |
| 3 | 刘备 |
+----+------+
3 rows in set (0.00 sec)Code language: JavaScript (javascript)
select * from person
where exists
(
select * from student where student.personid = person.id
);Code language: JavaScript (javascript)
查找person 去用person里面的每一条记录的值 带入到exists括号里面的select语句 然后如果这个括号里面的select语句 如果有值 不是空的话 那么就输出person的这条记录
比如person中的张飞 就相当于下面:
select * from student where student.personid = 1Code language: JavaScript (javascript)
发现有值 然后输出张飞的记录
再到下一个 关羽 刘备 一样符合 输出 但是到董卓的时候:
select * from student where student.personid = 4Code language: JavaScript (javascript)
就发现空的 然后不输出董卓
其实就比 把person查出每一条记录 作为参数 输入到exists里面 去判断
这个语句 就是利用person的值 去查找 如果有值 则返回true 空则返回false
如果是true 则输出当前的这个person行