MySQL 数据库中的EXISTS语句是一种条件查询语句,用于检查子查询中是否至少返回了一行数据。它通常与主查询一起使用,以判断是否满足某个条件。
EXISTS (subquery)
其中,subquery是一个子查询,用于检查是否存在满足条件的数据行。如果子查询返回至少一行数据,则EXISTS语句返回TRUE,否则返回FALSE。
以学生表和成绩表做本案例讲解。
这是详细信息得内容。
-- ---------------------------- -- Table structure for student -- ---------------------------- DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, `sex` varchar(11) COLLATE utf8_unicode_ci DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- ---------------------------- -- Records of student -- ---------------------------- INSERT INTO `student` VALUES ('1', '张三名', '男'); INSERT INTO `student` VALUES ('2', '李四浩', '男'); INSERT INTO `student` VALUES ('3', '王五期', '女'); INSERT INTO `student` VALUES ('5', '三七熊', '女'); -- ---------------------------- -- Table structure for course -- ---------------------------- DROP TABLE IF EXISTS `course`; CREATE TABLE `course` ( `id` int(11) NOT NULL AUTO_INCREMENT, `studentid` int(11) DEFAULT NULL, `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `score` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=16 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- ---------------------------- -- Records of course -- ---------------------------- INSERT INTO `course` VALUES ('1', '1', '语文', '81'); INSERT INTO `course` VALUES ('2', '1', '数学', '74'); INSERT INTO `course` VALUES ('3', '1', '英语', '56'); INSERT INTO `course` VALUES ('4', '2', '语文', '71'); INSERT INTO `course` VALUES ('5', '2', '数学', '77'); INSERT INTO `course` VALUES ('6', '2', '英语', '66'); INSERT INTO `course` VALUES ('7', '3', '语文', '61'); INSERT INTO `course` VALUES ('8', '3', '数学', '87'); INSERT INTO `course` VALUES ('9', '3', '英语', '86'); INSERT INTO `course` VALUES ('10', '4', '语文', '71'); INSERT INTO `course` VALUES ('11', '4', '数学', '57'); INSERT INTO `course` VALUES ('12', '4', '英语', '76');
student学生表原始数据
mysql> SELECT * from student; +----+-----------+------+ | id | name | sex | +----+-----------+------+ | 1 | 张三名 | 男 | | 2 | 李四浩 | 男 | | 3 | 王五期 | 女 | | 5 | 三七熊 | 女 | +----+-----------+------+
course成绩表原始数据
学生分别有语文、数学、英语三门成绩,studentid是student学生表的id
mysql> SELECT * from course; +----+-----------+--------+-------+ | id | studentid | name | score | +----+-----------+--------+-------+ | 1 | 1 | 语文 | 81 | | 2 | 1 | 数学 | 74 | | 3 | 1 | 英语 | 56 | | 4 | 2 | 语文 | 71 | | 5 | 2 | 数学 | 77 | | 6 | 2 | 英语 | 66 | | 7 | 3 | 语文 | 61 | | 8 | 3 | 数学 | 87 | | 9 | 3 | 英语 | 86 | | 10 | 4 | 语文 | 71 | | 11 | 4 | 数学 | 57 | | 12 | 4 | 英语 | 76 | +----+-----------+--------+-------+
查找成绩表是否有“生物”课成绩信息。
mysql> SELECT CASE WHEN EXISTS -> (SELECT * from course where name='生物') -> THEN '存在数据' -> ELSE '不存在数据' -> END; +------------------------------------------------------------------------------------------------------------+ | CASE WHEN EXISTS (SELECT * from course where name='生物') THEN '存在数据' ELSE '不存在数据' END | +------------------------------------------------------------------------------------------------------------+ | 不存在数据 | +------------------------------------------------------------------------------------------------------------+
子句实际运用,条件固定只会返回真或者假,以下条件为假,则主查询的每行都假则全部不输出
mysql> SELECT * from course where EXISTS (SELECT * from course where name='生物'); Empty set (0.00 sec)
以下条件为真,则主查询的每行都为真则全部输出
mysql> SELECT * from course where EXISTS (SELECT * from course where name='语文'); +----+-----------+--------+-------+ | id | studentid | name | score | +----+-----------+--------+-------+ | 1 | 1 | 语文 | 81 | | 2 | 1 | 数学 | 74 | | 3 | 1 | 英语 | 56 | | 4 | 2 | 语文 | 71 | | 5 | 2 | 数学 | 77 | | 6 | 2 | 英语 | 66 | | 7 | 3 | 语文 | 61 | | 8 | 3 | 数学 | 87 | | 9 | 3 | 英语 | 86 | | 10 | 4 | 语文 | 71 | | 11 | 4 | 数学 | 57 | | 12 | 4 | 英语 | 76 | +----+-----------+--------+-------+
在实际的场景都是运用动态条件,拿主查询的studentid查找student的id是否相等,就是是否有记录则输出
mysql> SELECT * from course c where EXISTS (SELECT * from student s where s.id=c.studentid); +----+-----------+--------+-------+ | id | studentid | name | score | +----+-----------+--------+-------+ | 1 | 1 | 语文 | 81 | | 2 | 1 | 数学 | 74 | | 3 | 1 | 英语 | 56 | | 4 | 2 | 语文 | 71 | | 5 | 2 | 数学 | 77 | | 6 | 2 | 英语 | 66 | | 7 | 3 | 语文 | 61 | | 8 | 3 | 数学 | 87 | | 9 | 3 | 英语 | 86 | +----+-----------+--------+-------+
在查询、修改、删除的时候在处理没有数据的时候是不会报错的,如果想报出错误可以使用EXISTS语句,以删除为例,id='15'的数据没有
mysql> DELETE FROM course where id=15; Query OK, 0 rows affected (0.01 sec)
加了EXISTS语句后有错误提醒信息
mysql> DELETE FROM course where EXISTS(SELECT * from course where id=15); ERROR 1093 (HY000): You can't specify target table 'course' for update in FROM clause
在使用EXISTS语句时,需要注意以下几点:
EXISTS语句通常与主查询一起使用,用于判断是否满足某个条件。它返回一个布尔值,而不是实际的查询结果。
EXISTS语句中的子查询不需要返回任何实际的列值,只需返回至少一行数据即可。通常使用SELECT 1作为子查询的查询语句。
EXISTS语句可以嵌套使用,即在一个EXISTS语句中使用另一个EXISTS语句。
mysql> SELECT * from course c where EXISTS (SELECT * from student s where EXISTS (SELECT * from student s2 where s2.id=5 )); +----+-----------+--------+-------+ | id | studentid | name | score | +----+-----------+--------+-------+ | 1 | 1 | 语文 | 81 | | 2 | 1 | 数学 | 74 | | 3 | 1 | 英语 | 56 | | 4 | 2 | 语文 | 71 | | 5 | 2 | 数学 | 77 | | 6 | 2 | 英语 | 66 | | 7 | 3 | 语文 | 61 | | 8 | 3 | 数学 | 87 | | 9 | 3 | 英语 | 86 | | 10 | 4 | 语文 | 71 | | 11 | 4 | 数学 | 57 | | 12 | 4 | 英语 | 76 | +----+-----------+--------+-------+
在使用EXISTS语句进行更新或删除操作时,需要小心谨慎,确保只更新或删除符合条件的行,避免意外删除或更新不应该修改的数据。
总的来说,EXISTS语句是一种非常有用的条件查询语句,可以用于判断子查询中是否存在满足条件的数据行。在使用时,需要根据具体的需求和情况选择合适的语法和案例,并注意一些潜在的问题和注意事项。