子查询就相当于嵌套查询,在一个select里面嵌套一个甚至多个查询,可以是多级嵌套。
分为三种情况:
查询所有学生的信息并显示老师的名字
select *,(
select name from teacher where id=teacher_id
) as teacher_name from student ;
注意:
select后面的子查询只能表示一列内容,写上表与表之间的关系。
使用子查询 对成绩划分等级, score<60 ,评级C 并且是差,score>=60 且 score<80 评级B并且是良,score>=80 评级是A并且是优
select *,
case rank
when 'A' then '优'
when 'B' then '良'
when 'C' then '差'
end rank_ch
from (
select *,
case
when score < 60 then 'C'
when score >=60 and score <80 then 'B'
when score >=80 then 'A'
end as rank
from student
) a;
注意:
因为子查询优先被执行,所以你想要调用子查询里面的内容,要给子查询加别名,用别名点调用
在不知道teacher_id 和 老师名字的对应关系的情况下,想查询出张老师下面的所有学生信息
select * from student where teacher_id in (
select id from teacher where name='张老师'
);
注意:
此时的子查询里面的select里面只能查一列,
如果select里面只有一行的话,子查询括号外面可以用=,如果是多行必须用in
select version() ;显示当前MySQL软件的版本
select database();显示当前所处数据库是哪个
select char_length('中国');返回字符个数。
select length('中国');返回字符所占字节数,MySQL中,一个UTF8编码的汉字占3个字节
select concat( 'a', 'b', 'c', 'd');返回 'abcd'。字符串拼接函数
select concat_ws( '=', 'a', 'b', 'c');返回 'a=b=c'。字符串拼接函数,第一个是拼接间隔符
select upper('abcd');返回ABCD。将参数中所有小写字母转换为大写
select lower('ABCD');返回abcd。将参数中所有大写字母转换为小写
select substring( '系统信息类', 1, 3 );返回 系统信。第2个参数代表从1开始的第几个字符,第3个参数代表截取字符个数
select trim(' abc ');返回 abc。用于删去参数左右的所有空格
select curdate();返回当前日期
select curtime();返回当前时间
select now();返回当前日期时间
select unix_timestamp();返回当前日期时间对应的时间戳(单位秒)
select unix_timestamp('2018-05-24 20:00:00');返回参数指定的日期时间对应的时间戳(单位秒)
select from_unixtime(1527163397);返回参数指定时间戳(单位秒)对应的日期时间
select datediff( '2018-05-23', now() );返回两个参数对应日期相差的天数(用第一个参数减第二个参数)
select adddate( now(), -2 );返回指定天数前/后的日期时间(第一个参数是日期时间,第二个参数是天数,向后加是正数,向前减是负数)
select year('2019-02-24');返回2019 获得年份
select month('2019-02-24') 返回2 获得月份
select day('2019-02-24') 返回 24 获取日
select if( <判断条件>, <条件为真时的返回值>, <条件为假时的返回值> );相当于Java中的三目运算符<判断条件> ? <条件为真的返回值> : <条件为假的返回值>。
如select if(1=1, 2, 3);返回2。
select ifnull(<表达式或者字段>, <表达式或者字段为NULL时的返回值>);通常用于给有可能有NULL的情况下的提供默认值。
select ifnull(null,'无名氏') ; null这里可以写列名 就会把该列值为null的 以无名氏显示
select ifnull(name,'无名氏') from teacher ;
在用多表查询时,可以用子查询形式去查询,也可以用连接查询的方式去查,连接查询时如果不用限制条件而是直接使用from然后逗号隔开两个甚至多个表名,那么会发生笛卡尔乘积,这是会很消耗内存的运算的,这里我们可以用根据寻求选择inner/left/right…join 形式
select *
from teacher tea
inner join student stu on tea.id = stu.teacher_id;
join 中常与on 连用,on 后面书写表与表之间的联系列。
在使用 join 连接查询 时,on和where条件的区别:
注意:
使用内连接的话,会以左边表为基准(student),生成新视图的时候,先生成左边表中的数据,然后再去匹配右边表中是否有符合条件的,没有的话,就不生成这一行
同时左表中有的,右表中没有的数据,都不会生成
右表中有的,左表中没有的也一样不会生成,所以 左表和右表就算换了位置,数据行数不会变多
但是会丢失数据,不符合条件的数据不会查询出来。
多表查询是有左右表之分的,一般左表是主表,以左边为主
查询结果,显示小红,但是不显示孙老师
select * from student s
left join teacher t on s.teacher_id = t.id;
以左边的表为基准,左表中数据都有,右表中不符合条件的就没有,就在指定列上用null代替
生成视图的时候,也是先生成左表的数据
查询结果,显示孙老师,但是不显示小红
select * from student s
right join teacher t on s.teacher_id = t.id;
以右表为基准,右表中数据都有,左表中不符合条件的就没有,就在指定列上用null代替
但是视图生成的时候,还是会先生成左表数据
当使用join时,能用inner(内连接)的尽量不用left/right(外连接) ,而right最少用,因为他是原理和left差不多只要把left的表置换一下位置就行。
外键与表连接没有任何关系。
外键是为了保证你不能随便删除/插入/修改数据,是数据完整性的一种约束机制。
表连接是因为一张表的字段无法满足业务需求(你想查的字段来自于2张甚至多张表)
一个是为了增删改,一个是为了查,它俩之间没有联系。