MYSQL-02课堂笔记
day02课堂笔记
1、把查询结果去除重复记录
   注意:原表中数据不会被修改,只是查询结果去重
   去重需要一个关键字:distinct
   select distinct job from emp;
   
   //这样编写是错误的,语法错误
   //distinct只能出现再所有字段的最前方
   select ename,distinct job from emp;
    //distinct 出现再job,deptno两个字段之前,表示两个字段联合起来去重
    select distinct job,deptno from emp;
统计工作岗位的数量
select count(distinct job) from emp;
2、连接查询
2.1、什么是连接查询?
      从一张表中单独查询,称为单表查询
      emp和dept表联合起来查询数据,从emp表中取员工名字,从dept表中取部门名字
      这种跨表查询,多张表联合起来查询数据,被称为连接查询
2.2、连接查询的分类?
      根据语法的年代分类
         SQL92:1992年出现的语法
	 SQL99:1999年出现的语法
	
      根据表连接的方式分类
         内连接:
      等值连接
      非等值连接
      自连接
	  外连接:
    左外连接(左连接)
    右外连接(右连接)
     全连接
	当两张表进行连接查询,没有任何条件限制的时候,最终查询结果条数,是两张表条数的乘积,
	这种现象被称为:笛卡尔积现象(数学现象)
	select ename,dname from emp,dept;
会有56行记录
    2.3、怎么避免笛卡尔积现象?
         连接时加条件,满足这个条件的记录会被筛选出来!
           select 
	      ename,dname
	   from 
	      emp,dept
	   where 
	       emp.deptno=dept.deptno;
        
	最终查询结果条数是14条,但是匹配过程中,匹配的次数减少了吗?
      还是56次,只不过进行了四选一,次数没有减少
注意:通过笛卡尔积现象得出,表的连接次数越多效率越低,尽量避免表的连接次数。
3、内连接
3.1、内连接---等值连接
   案例:查询每个员工所在部门的名称,显示员工名和部门名?
   emp e和dept d表进行连接,条件是:e.deptno=d.deptno
SQL92的语法
select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;
   SQL92的缺点:结构不清晰,表的连接条件,和后期进一步筛选的条件,都放到了where后面
SQL99的语法
select e.ename,d.dname from emp e join dept d where e.deptno=d.deptno;
     SQL99的缺点:表连接的条件是独立的,连接之后,如果还需要进一步的筛选,再往后继续添加where
SQL99的语法
select ... from a join b on a和b的连接条件 where 筛选条件
3.2、内连接---非等值连接
案例:找出每个员工的薪资等级,要求显示员工名,薪资,薪资等级
select e.ename,e.sal,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;//条件不是一个等量关系,称为非等值连接
3.3、内连接---自连接
 案例:查询员工的上级领导,要求显示员工名和对应的领导名?
       技巧:将一张表看成是两张表
         select 
	   a.ename as '员工名' ,b.ename as '领导名'
	 from
	    emp a
	 join
	    emp b
	 on
	    a.mgr=b.empno;//员工的领导编号=领导的员工编号
     13条记录,没有king(内连接)
以上就是内连接中的自连接,技巧:一张表看成是两张表
4、外连接
内连接:
select e.ename,d.dname from emp e join dept d where e.deptno=d.deptno;//内连接的特点:完成能够匹配上这个条件的数据查询处理
外连接(右外连接):
select e.ename,d.dname from emp e right join dept d where e.deptno=d.deptno;
select
e.ename,d.dname
from
emp e
right join
dept d
where
e.deptno=d.deptno;//外连接的特点:完成能够匹配上这个条件的数据查询处理,还要将主表中剩余的没有与副表中匹配的数据显示出来
       外连接(左外连接):
select e.ename,d.dname from dept d left join emp e where e.deptno=d.deptno;
 
5、三张表怎么连接?
    语法:
select ... from ... join b on a和b 的连接条件 join c on a和c 的连接条件 join d on a和d 的连接条件
    一条SQL语句中内连接和外连接可以混合使用,都可以出现!
    案例:找出每个员工的部门名称以及工资等级,
    要求显示员工名,部门名,薪资,薪资等级?
select e.ename,d.deptno,s.grade from emp e join dept d on e.deptno=e.deptno join salgrade s on e.sal bewteen s.losal and hisal;
    案例:找出每个员工的部门名称,以及工资等级,还有上级领导,
    要求显示员工名、领导名、部门名、薪资,薪资等级
select e.ename,d.dname,e.sal,s.grade,t.ename from emp e join dept d on e.deptno=d.deptno join salgrade s on e.sal between s.losal and hisal left join emp t on e.mgr=t.empno;
6、子查询?
6.1、什么是子查询?
select语句中嵌套select语句,被嵌套的select语句被称为子查询。
6.2、子查询都可以出现在哪里呢
select ...(select) from ...(select) where ...(select)
6.3、where字句中的子查询
 
      案例:找出比最低工资高的员工的姓名和工资
        select 
	   ename,sal
	from 
	   emp
	where 
	   sal<min(sal)
     错误:where子句中不能直接使用分组函数。
    
     实现思路:
        第一步:查询最低工资是多少
select min(sal) from emp;
	第二步:找出>800的
select ename,sal from emp where sal>800;
	第三步:合并
select ename,sal from emp where sal>(select min(sal) from emp);
6.4、from 子句中的子查询
       注意:from后面的子查询,可以将子查询的查询结果当作是一张临时表(子查询)
	 
       案例:找出每个岗位的平均工资的薪资等级
第一步:找出每个岗位i的平均工资
select job,avg(sal) from emp group by job;
        第二步:克服心里障碍,把以上的查询结果当作是一张真实存在的表t
t表和s表进行表连接,条件:t表avg(sal) between s.losal and s.hisal;
select t.*,s.grade from (select job,avg(sal) as avgsal from emp group by job) t join salgrade s on t.avgsal between s.losal and s.hisal;
    6.5、select 后面出现的子查询(了解即可)
      案例:找出每个员工的部门名称,要求显示员工名,部门名?
select e.ename ,(select d.dname from dept d where e.deptno=d.deptno) as dname from emp e;
select e.ename ,(select d.dname from dept ) as dname from emp e;
 错误:对于select 后面的子查询来说,这个子查询只能一次返回一条结果
       多于一条,就报错!
7、union合并查询结果集
 
   案例:查询工作岗位是manager和salesman的员工?
select ename, job emp where job='manager' or job='saleman'; select ename,job from emp where job in('manager','salesman');
	使用union
select ename,job from emp where job='manager' union select ename,job from emp where job='salesman';
    union的效率要高一些,对于表连接来说,每连接一次新表
    则匹配的次数满足笛卡尔积,成倍的翻。。。
    但是union可以减少匹配的次数,在减少匹配的情况下
    还可以完成两个结果的拼接
    a 连接 b 连接 c
    a 10条记录
    b 10条记录
    c 10条记录
    匹配次数是:1000
    a 连接 b 一个结果:10*10-->100次
    a 连接 c  一个结果:10*10 -->100次
    使用union的话是:100 +100=200(union把乘法变成了加法运算)
 union在使用的时候有注意事项?
    1.union在进行结果集合并的时候,要求两个结果集的列数相同
select ename,job from emp where job='manager' union select ename from emmp where job='salesman';
    2.要求:结果集合并列与列的数据类型也要相同
select ename,job from emmp where job='manager' union select ename,sal from emp where job='salesman';
8、limit
8.1、limit的作用:将查询结果集的一部分取出来 通常使用在分页查询当中
   百度默认:一页显示10条记录。
   分页的作用:为了提高客户的体验,因为一次全部都查出来,用户提样差
   可以一页一页的翻着看
8.2、limit怎么用呢?
     完整用法:limit startIndex,length
缺省用法:limit 5;这里取前五;
按照薪资降序,取出排在前五的员工?
select ename,sal from emp order by sal desc limit
5; select ename,sal from emp order by sal desc limit
0,5;
8.3、注意:MySQL当中的limit在order by 之后执行!!!!
8.4、取出工资排名在【3-5】名的员工?
select ename,sal from emp order by sal desc limit 2,3
 2表示起始位置从下标2开始,就是第三条记录
      3表示长度
    8.5、取出工资排名在【5-9】名的员工?
select ename,sal from emp order by sal desc limit 4,5;
8.6、分页
 每页显示3条记录
       第一页:limit 0,3  [0 1 2]
       第二页:limit 3,3  [3 4 5]
       第三页:limit 6,3  [6 7 8]
       第四页:limit 9,3  [9 10 11]
    每页显示pageSize条记录
      第pageNo页:limit (pageNo-1) *pageSize, pageSize
      public static void main(String [] args){
         //用户提交一个页码,以及每页显示的记录条数
	 int pageNo =5;//第五页
	 int pageSize=10;//每页显示10条
	 int  startIndex=(pageNo-1)*pageSize;
	 String sql="select ... limit "+startIndex+","+pageSize;
      }
	 
    记公式:
       limit (pageNo-1)*pageSize,pageSize 
9、关于DQL语句的大总结
select ... from ... where ... group by .... having ... order by ... limit ...
   执行顺序:
     1.from
     2.where
     3.group by
     4.having 
     5.select
     6.order by
     7.limit ..
10、表的创建(建表)
10.1建表的语法格式(建表属于DDL语句,DDL语句包括:create drop alter)
      create table 表名(字段名 数据类型,字段名2 数据类型, 字段名3 数据类型);
      create table 表名(
           字段名1 数据类型,
	   字段名2 数据类型, 
	   字段名3 数据类型
	   );
     表名:建议以t_或者tbl_开始,可读性强,见名知意
     字段名:见名知意。
     表名和字段名都属于表示符。
10.2、关于mysql中的数据类型?
         很多数据类型,我们只需要掌握一些常见的数据类型即可。
	    varchar(最长255) 
	       可变长度的字符串
	       比较智能,节省空间
	       会根据实际的数据长度动态的分配空间
	       优点:节省空间
	       缺点:需要动态的分配空间,速度慢
	    char(最长255)
	       定长字符串
	       不管实际的字符长度是多少
	       分配固定长度的空间取存储数据
	       使用不当的时候,可能会造成空间的浪费
	       优点:不需要动态的分配空间,速度快
	       缺点:使用不当会造成空间的浪费
	    varchar 和char我们怎么选择?
	        性别字段你选什么?因为性别是固定长度的字符串,所以选择char
		姓名字段选什么?每个人的名字长度不同,所以你选择varchar
            int (最长11)
                数字中的整型,等同与java中的int
	    bigint
                 数字中的长整型,等同于Java中的long
	    float
                单精度浮点型
	    double
                双精度浮点型
	    date
                短日期类型
            datetime
	        长日期类型
            clob 
               字符大对象
	       最多可以存储4G的字符串
	       比如:存储一篇文章,存储一个说明
	    blob
	       二进制大对象
	       Binary Large OBject
	       专门用来存储图片,声音,视频等流媒体。
	       你需要使用IO流才行
      7.3、创建一个学生表?
           学号,姓名,年龄,性别,邮箱地址
create table t_student{ no int, name varchar(32), sex char(1), age int(3), email varchar(255) };
删除表
drop table t_student;//当这张表不存在时会报错! drop table if exits t_student;//如果这张表存在的话,删除
7.4、插入数据insert(DML)
           语法格式:
	      insert into 表名(字段名1,字段名2,字段名3……) values(值1,值2,值3);
	     
	      注意:字段名和值要一一对应,数量要相同,数据类型要对应。
insert into t_student(no,name,sex,age,email) values(1,'zhangsan','m',20,'zhangsan@123'); insert into t_student(no) values(3); insert into t_student(name) values('wangwu');
	   注意:insert语句但凡是执行成功了,那么必然会多一条记录
	   没有给其他字段指定值的话,默认值为null
也可以设置默认值
drop table if exits t_student; create table t_student( no int, name varchar(32), sex char(1) default 'm', age int(3), email varchar(255) ); insert into t_student(no) values(1);
	   //注意:前面的字段名省略的话,等于都写上了,所有值也要都写上!
	   insert into t_student values(2);//错误
	   insert into t_student values(2,'lisi','f',20,'lisi@123.com');
7.5、insert 插入日期
 
	   数字格式化:format
	  格式化数字:format(数字,'格式')
select ename,format(sal,'$ 999.999') as sal from emp;
str_to_date:将字符串varchar类型转换成date类型
date_format:将date类型转换成一定格式varchar类型
drop table if exits t_user; create table t_user( id int, name varchar(32), birth date//生日使用字符串,没问题 );
 注意:数据库中的一条命名规范:
	      所有的标识符都是全部小写的,单词和单词之间使用下划线进行衔接
          
	  插入数据?
	     insert into t_user(id,name,birth) values(1,'zhangsan','01-10-1990');//1990年10月1日
             出问题:原因是类型不匹配,数据库birth是date类型,这里给了一个字符串varchar
 怎么办?可以使用str_to_date函数进行类型匹配。
	     str_to_date函数可以将字符串转换成日期类型date?
	     语法格式:
	        str_to_date('字符串日期','日期格式')
	     
	     mysql的日期格式:
	        %Y 年
		%m 月
		%d 日
		%h 时
		%i 分
		%s 秒
insert into t_user(id,name,birth) values(1,'zhangsan',str_to_date('01-10-1990','%d-%m—%Y'));
	str_to_date函数可以把字符串varchar转换成date类型
	通常使用在插入insert方面,因为插入的时候需要一个日期类型的数据
	需要通过该函数将字符串转换成date
如果你提供的日期是:%Y-%m-%d这个格式,str_to_date函数就不需要了!!!
insert into t_user(id,name,birth) values(2,'lisi','1990-10-01');
	查询的时候可以以某个特定的日期格式展示吗?
	   date_format
	   这个函数可以将日期类型转换成特定格式的字符串。
select id,name,date_format(birth,'%m%d%Y' ) as birth from t_user;
	   date_format函数怎么用?
	       date_format(日期类型数据,'日期格式')
	       这个函数通常使用在查询日期方面,设置展示的日期格式
	   select id ,name ,birth from t_user;
	   以上的SQL语句实际上是进行了默认的日期格式化。
	   自动将数据库中的date类型转换为varchar类型
	   并且采用的格式是mysql默认的日期格式:%Y-%m-%d
7.6、date和datetime两个类型的区别?
          date是短日期:只包含年月日信息
	  datetime是长日期:包括年月日时分秒信息
drop table if exits t_user; create table t_user( id int, name varchar(32), birth date, create_time datetime );
 mysql短日期默认格式:%Y-%m-%d
	 mysql长日期默认格式:%Y-%m-%d %h:%i:%s
         在MySQL中怎么获取系统当前时间?
	     now()函数,并且获取的时间带有:时分秒信息!!!是datetime类型的
insert into t_user(id,name,birth,create_time) values(2,'lisi','1990-10-01',now()); insert into t_user(id,name,birth,create_time) values(2,'lisi','1990-10-01','2022-01-10 13:09-01');
10.7、修改update(DML)
           语法格式:
         update 表名 set 字段名=值1,字段名=值2,字段名=值3…… where条件
注意没有条件限制会导致所有的数据更新
update t_user set name='jack',birth='2000-10-11' where id=2;
更新所有?
update t_user set name='abc';
10.8、删除数据delete(DML)
        语法格式:
	   delete from 表名 where 条件;
注意:没有条件,整张表的数据会被全部删除!
delete from t_user where id=2; insert into t_user(id) values(2); delete from t_user;//删除所有
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号