MySQL自连接与子查询方式
作者:_周游
1. 自连接
自连接是表自身与自身做笛卡尔积,在SQL中进行条件查询,都是指定某一列或多个列之间进行关系运算,无法进行行与行之间的运算,在某些情况下需要对行与行之间进行关系运算,就要使用到自连接。
自连接的本质是将行转为列;
示例:显示所有“课程id为3”比“课程id为1”成绩高的成绩信息:
(成绩信息在score表中)
(1)对score进行自连接(别名求笛卡尔积)并删除无效信息:
mysql> select* from score as s1, score as s2 where s1.student_id = s2.student_id;
(2)选出第一列id=1的课程与第二列id=3的课程:
mysql> select* from score as s1, score as s2 -> where s1.student_id = s2.student_id -> and s1.course_id = 1 -> and s2.course_id = 3;
(该结果表示有三个同学同时选修了这两门课程)
(3)增加左列成绩小于右列成绩条件,SQL指令与查询结果为:
mysql> select* from score as s1,score as s2 -> where s1.student_id = s2.student_id -> and s1.course_id = 1 -> and s2.course_id = 3 -> and s1.score < s2.score; +-------+------------+-----------+-------+------------+-----------+ | score | student_id | course_id | score | student_id | course_id | +-------+------------+-----------+-------+------------+-----------+ | 70.5 | 1 | 1 | 98.5 | 1 | 3 | | 33.0 | 3 | 1 | 68.0 | 3 | 3 | +-------+------------+-----------+-------+------------+-----------+ 2 rows in set (0.00 sec)
注:
(1)不能直接进行自连接:
mysql> select* from score,score; ERROR 1066 (42000): Not unique table/alias: 'score'
需要为表指定两个别名,即:
mysql> select* from score as s1, score as s2;
2. 子查询(嵌套查询)
子查询是指嵌入其他SQL语句中的select语句,即将多个查询语句合并为一个语句;
2.1 子查询分类
(1)单行子查询:查询结果只有一条记录;
(2)多行子查询:查询结果为多条记录;
2.2 单行子查询示例1:查询不想毕业同学的同班同学
(1)分步查询SQL指令及查询结果为:
mysql> select classes_id from student where name="不想毕业"; +------------+ | classes_id | +------------+ | 1 | +------------+ 1 row in set (0.00 sec) mysql> select name from student where classes_id =1; +------------+ | name | +------------+ | 黑旋风李逵 | | 菩提老祖 | | 白素贞 | | 许仙 | | 不想毕业 | +------------+ 5 rows in set (0.00 sec)
(2)子查询SQL指令及查询结果为:
mysql> select name from student where classes_id = (select classes_id from student where name="不想毕业"); +------------+ | name | +------------+ | 黑旋风李逵 | | 菩提老祖 | | 白素贞 | | 许仙 | | 不想毕业 | +------------+ 5 rows in set (0.00 sec)
即将条件查询的某一个值替换为一个select查询语句;
2.3 多行子查询示例2:查询语文或英语课程的信息成绩
先查询出两个课程的课程id,再根据course_id在score表中查询;
(1)分步查询SQL指令及查询结果为:
mysql> select id from course where name="语文" or name="英文"; +----+ | id | +----+ | 4 | | 6 | +----+ 2 rows in set (0.00 sec) mysql> select* from score where course_id in(4,6); +-------+------------+-----------+ | score | student_id | course_id | +-------+------------+-----------+ | 98.0 | 1 | 6 | | 72.0 | 4 | 6 | | 43.0 | 6 | 4 | | 79.0 | 6 | 6 | | 92.0 | 7 | 6 | +-------+------------+-----------+ 5 rows in set (0.00 sec)
(2)子查询SQL指令及查询结果为:
mysql> select* from score where course_id in(select id from course where name="语文" or name="英文"); +-------+------------+-----------+ | score | student_id | course_id | +-------+------------+-----------+ | 98.0 | 1 | 6 | | 72.0 | 4 | 6 | | 43.0 | 6 | 4 | | 79.0 | 6 | 6 | | 92.0 | 7 | 6 | +-------+------------+-----------+ 5 rows in set (0.00 sec)
3. 合并查询
合并查询就是将两个查询语句的结果合并到一起;
3.1 示例1:查询id=3或者名字为英文的课程
(1)使用逻辑或实现查询:
mysql> select* from course where id<3 or name="英文"; +----+--------------+ | id | name | +----+--------------+ | 1 | Java | | 2 | 中国传统文化 | | 6 | 英文 | +----+--------------+ 3 rows in set (0.00 sec)
(2)使用union关键字进行合并查询:
mysql> select* from course where id<3 union select* from course where name="英文"; +----+--------------+ | id | name | +----+--------------+ | 1 | Java | | 2 | 中国传统文化 | | 6 | 英文 | +----+--------------+ 3 rows in set (0.00 sec)
注:
(1)union与逻辑或的区别:
逻辑或只能对一张表的查询结果进行合并,但union可以对多张表的查询结果进行合并(要求多个结果的列须对应);
(2)union与union all的区别:
使用union关键字对多个查询结果进行合并时会自动去重,但unionall不会去重;
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。