MySQL基础学习笔记(2)

关于查询结果集的去重
    select distinct job from emp;
    distinct出现在所有字段最前方,表示联合去重
    统计岗位的数量:select count(distinct job) from emp;

连接查询
    实际开发中,单表查询数据使用场景有限,一般是多张表联合查询
    一个业务对应多张表,如,学生和班级

连接查询的分类
    SQL92(DBA 数据库管理员)
    SQL99(比较新的)
    表的连接方式包括:
        内连接
            等值连接
            非等值连接
            自连接
        外链接
            左外连接
            右外连接
        全连接(很少用)
    --------
    笛卡尔积现象:
        两张表进行连接查询,没有进行任何限制时,最终查询结果是两张表记录条数的乘积。
    找出每一个员工的部门名称,要求显示员工名和部门名。
    select ename,dname from emp,dept;(出现迪卡尔积现象)
    --------
    
关于表的别名:
    select e.ename,d.dname from emp e dept d;
    表的别名有什么好处?
        1.执行效率高
        2.可读性好
        
避免笛卡尔积现象,加条件进行过滤,但不会记录减少匹配次数
    找出每一个员工的部门名称,要求显示员工名和部门名。
    select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;//SQL92,以后不用
    
内连接之等值连接:连接条件是等量关系
    找出每一个员工的部门名称,要求显示员工名和部门名。
    select e.ename,d.dname from emp e (inner) join dept d on e.deptno=d.deptno;//SQL99
    inner可以省略,带着inner可读性好
    99语法:(优点:表连接条件与数据过滤条件where分离,结构清晰)
        ...
            A
        join
            B
        on
            连接条件
        where
            ...
            
内连接之非等值连接:连接条件是非等量关系
    找出每个员工的工资等级,要求显示员工名、工资、工资等级。
    select 
        e.ename,e.sal,s.grade
    from
        emp e
    join
        salgrade s
    on
        e.sal between s.losal and hisal;
        
内连接之自连接:一张表看作两张表
    找出每个员工的上级领导,要求显示员工名和对应的领导名
    select empno,ename,mgr from emp;
    select
        a.ename as '员工名',b.ename as '领导名'
    from
        emp a
    inner join
        emp b
    on
        a.mgr=b.empno;  //SQL中=表示等于逻辑运算,不是赋值运算
    
外连接
    内连接,凡是两张表能够匹配上的记录查询出来,两张表没有主副之分,是平等的。
    外连接,两张表有主副之分,主要查询主表的数据,当副表中没有与主表相匹配的数据时,副表会自动模拟出NULL与之匹配。
    左外连接(左连接):表示左边的是主表
    右外连接(右连接):表示右边的是主表
    左右连接 可以互换写法。
    查询每个员工的领导:select a.ename,b.ename from emp a left join emp b on a.mgr=b.empno;
    外连接最大的特点,主表的数据无条件全部查询出来。
    --------
    找出哪个部门没有员工?
    select
        d.* 
    from
        emp e 
    right join 
        dept d 
    on 
        e.deptno=d.deptno 
    where 
        e.empno is null; //副表会自动模拟出NULL
    --------
    
3张表怎么连接查询?
    找出每一个员工的名称以及工资等级
        ...
            A
        join
            B
        join
            C
        on
            ...
        表示:A表先和B表进行连接,之后A表继续和C表进行连接。
        select 
            e.ename,d.dname, s.grade
        from
            emp e
        join
            dept d
        on
            e.dept=d.dept
        join
            salgrade s
        on
            e.sal between s.losal and s.hisal;
    找出每一个员工的部门名称、工资等级和上级领导
        select 
            e.ename,g.ename,d.dname, s.grade
        from
            emp e
        left join  // 左外连接
            emp g
        on 
            e.mgr=g.empno
        join
            dept d
        on
            e.dept=d.dept
        join
            salgrade s
        on
            e.sal between s.losal and s.hisal;

子查询
    什么是子查询,子查询可以出现在哪里?(p37 where后面嵌套子查询)
    select语句嵌套select语句,被嵌套的select语句是子查询。
    select
        ...(select)
    from
        ...(select)
    where
        ...(select)
    
    --------
    where字句中使用子查询
    找出高于平均薪资的员工信息
    select * from emp where sal > avg(sal); //错
    select * from emp where sal > (select avg(sal) from emp);
    --------
    from字句中使用子查询(常用)********
    找出每个部门平均薪水的薪资等级
        第一步 每个部门的平均薪资:
        select deptno,avg(sal) as avgsal  from emp group by deptno;
        第二步 每个部门平均薪资对应的等级:
        select
            t.*,s.grade 
        from 
            (select deptno,avg(sal) as avgsal  from emp group by deptno) t 
        join
            salgrade s  
        on
            t.avgsal 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;
    找出每个部门平均的薪资等级
    找到每个人对应的薪资等级:
        select
            e.deptno,avg(s.grade)
        from 
            emp e 
        join 
            salgrade s 
        on 
            e.sal between s.losal and s.hisal  
        group by                               
            e.deptno;
        

        select
            t.deptno,avg(t.grade)
        from 
            (select e.ename,e.deptno,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal) t 
        group by
            t.deptno;
    --------
    select字句中使用子查询
    找出每个员工所在部门名称,显示员工名和部门名。
        select e.ename,d.dname from emp e join dept d on e.deptno=d.deptno;
        select e.ename,(select d.dname from dept d where e.deptno=d.deptno) as dname from emp e;
    ---------

union(可以将查询结果集相加)
    找出工作岗位是salesman和manager的员工?
    第一种:select ename,job from emp where job='salesman' or job='manager';
    第二种:select ename,job from emp where job in ('salesman','manager');
    第三种:select ename,job from emp where job='salesman'
            union
            select ename,job from emp where job='manager';
    两张不相干的表查询结果的合并就只能用 union.
    
limit的使用(重点中的重点,分页查询)
    limit是MySQL特有的,其它数据库没有
    limit取结果集中的部分数据。
    语法机制: limit startIndex,length
    --------
    取出工资前5名:(薪资降序取前5个)
    select ename,sal from emp order by sal desc;
    select ename,sal from emp order by sal desc limit 0,5;
    limit是SQL语句最后执行的一个环节。
        select    5
            xxx
        from    1
            xxx 
        where    2
            xxx
        group by 3
            xxx
        having    4
            xxx
        order by    6
            xxx
        limit
            xxx  7
    找出工资排名在第4到第9名的员工
        select ename,sal from emp order by sal desc limit 3,6;
    --------
    
通用的标准分页sql?
    每页显示3条记录:
    第一页:0,3
    第二页:3,3
    第三页:6,3
    ...
    每页显示pageSize条记录:
    第pageSize页:3*(pageSize-1),3
    java代码{
        int pageNo=2;
        int pageSize10;
        
        limit pageSize*(pageNo-1),10;
    }
DQL语句结束    
    
    
表的创建
    建表语句:create table 表名(
        字段名1  数据类型
        字段名2     数据类型
        ...
    );
    --------
    关于MySQL中常见字段的数据类型?
        int  整数
        bigint    长整型(java中的long)
        float    (String)
        fouble    (StringBuffer或StringBuilder)
        char    定长字符串
        varchar 变长字符串(最多255的字符)
        date    日期类型(对应java.sql.Date类型)
        BLOB(二进制大对象,存储图片、视频等流媒体信息)
        CLOB(字符大对象,存储较大文本,比如可以存储4G的字符串)
    --------
    char和varchar怎么选择?
        
    --------
    表名在数据库中一般建议以:t_或者tbl_开始
    创建学生表
        信息包括:
            学号、姓名、性别、班级编号、生日
            学号:bigint
            姓名:varchar
            性别:char
            班级编号:int
            生日:char
    create table t_student(
        no bigint,
        name varchar(255),
        sex char(1),
        classno varchar(255),
        birth char(10)
    );
    
insert语句插入数据
    语法格式:
        insert into 表名(字段1,字段2,字段3,...) values(值1, 值2, 值3,...);
        要求 字段的数量和值的数量相同,并且数据类型对应相同,顺序不必相同,前后对应就行,
        insert into t_student(no,name,sex,classno,birth) values(1,'zhangsan','1','gaosan1ban','1980-10-12');
        insert into t_student(name,sex,classno,birth,no) values('lisi','1','gaosan1ban','1980-10-12',2);
        insert into t_student(name) values("wanghwu"); //除name字段,剩下自动插入NULL
        insert into t_student()
    --------
    drop table if exists t_student;//表若存在删除
        create table t_student(
        no bigint,
        name varchar(255),
        sex char(1) default 1,
        classno varchar(255),
        birth char(10)
    );
    insert执行成功,表格中间会增加一条记录。
    --------
    insert into t_student values(3,'huao','0','gaosan2ban','1981-12-10');
    此时,顺序与数量必须与建表时匹配
    一次插入多行数据
    insert into t_student
        (no,name,sex,classno,birth) 
    values
        (4,'rose','1','gaosan2ban','1980-02-03'),(5,'laotie','1','gaosan2ban','1981-02-03');
    
表的复制
    语法:create table 表名 as select语句;
    将查询结果当作表创建出来。
    create table dept1 as select * from dept;
    
将查询结果插入到一张表中
    语法:insert into dept1 select * from dept;
    
修改数据库
    语法格式:update 表名 set 字段名1=值1,字段名2=值2... where 条件;
    注意:没有条件整张表数据全部更新。
    --------
    将部门10的loc修改为sahnghai,部门名修改为renshibu
    update dept1 set loc='shanghai',dname='renshibu' where deptno=10;
    update语句中的','不要写成and.
    更新所有记录 update dept1 set loc='x',dname='y';
    --------

删除数据
    语法:delete from 表名 where 条件;
    注意:没有调价全部删除
    删除10部门数据 delete from dept1 where deptno=10;
    删除所有数据:delete from dept1;
    --------
    delete语句删除数据慢,没有释放数据的真实存储空间,删完可以后悔回滚rollback!
    
    怎么删除大表中的数据?(重点)  删除之后无法恢复(删之前确认两遍)
    truncate table emp1;//表被截断,不可回滚。永久丢失。
    --------
    删除表?
        drop table 表名; // 通用
        drop table if exists 表名; //oracle不支持

DQL(select) DML(insrt delete update) DDl(create drop alter)数据定义语言    
关于表结构的修改(alter)
    使用工具,修改表结构的代码不会出现在java代码中。出现在java代码中的sql包括:
    insert delete update select(这些都是表中的数据操作)
    增删该查一个术语 CRUD
    Create(增)  Retrieve(检索)  Update(修改)  Delete(删除)
    
    
约束作用及常见约束
    Constraint
    什么是约束?常见的约束有哪些?
        表格
        id       username(唯一性约束)       password(非空约束)
        ------------------------------------------------------
    添加约束目的是为了保证表中数据的合法性、有效性、完整性。
    非空约束(not null)          字段不能为空
    唯一约束(unique)          字段不能重复
    主键约束(primary key)      既不能空,也不能重复 pk
    外键约束(foreign key)      ...                 fk
    检查约束(check) ORACLE数据库有,mysql不支持该约束
    
非空约束 not null
    drop table if exists t_user;
    create table t_user(
        id int,
        username varchar(255) not null, //注意:not null只有【列级约束】
        password varchar(255)
    ); 
    insert into t_user(id,password) values(1,'123'); //error 1366 非空约束
    会导致java程序异常,异常处理
    insert into t_user(id,username,password) values(1,'rose','123'); //ok
    
唯一性约束unique
    唯一约束修饰的字段具有唯一性,不能重复。但可以为NULL,NULL为空,不是具体的值
    drop table if exists t_user;
    create table t_user(
        id int,
        username varchar(255) unique
    ); 
    insert into t_user values(1,'zhangsan');
    insert into t_user values(2,'zhangsan');
    --------
    多个字段联合唯一,联合不能重复
    drop table if exists t_user;
    create table t_user(
        id int,
        usercode varchar(255),
        username varchar(255)
        unique(usercode,username) //多个字段联合添加约束【表级约束】
    ); 
    --------
    drop table if exists t_user;
    create table t_user(
        id int,
        usercode varchar(255) unique, //【列级约束】
        username varchar(255) unique
    ); 
    insert into t_user values(1,111,'zhangsan');
    insert into t_user values(2,111,'zhangsan');
    
主键约束
    怎么给一张表添加主键约束?
    drop table if exists t_user;
    create table t_user(
        id int primary key,    //【列级约束】
        username varchar(255), //注意:not null只有【列级约束】
        email varchar(255)
    ); 
    insert into t_user(id,username,email) values(1,'zs','zs@123.com'); 
    insert into t_user(id,username,email) values(2,'ls','ls@123.com'); 
    insert into t_user(id,username,email) values(3,'ww','ww@123.com'); 
    --------
    主键约束:主键中约束既不能空,也不能重复。
    主键相关的术语:
        主键约束、主键字段、主键值
    主键约束有什么用?
        表的设计三范式,第一范式要求任何一张表中要有主键。
        作用:主键值是这行记录在这张表中的唯一标识(身份证号一样)
    一张表的主键约束只能由一个.
    --------
    主键的分类
        根据主键字段的数量来划分:
            单一主键
            复合主键(多个字段联合起来添加一个主键约束,但不建议用).
        根据主键的性质来划分:
            自然主键:主键值最好就是一个和业务没有任何关系的自然数。
            业务主键:主键和系统的业务挂钩,如用银行卡的卡号做主键,身份证号码做主键。
            
外键约束
        外键约束(foreign key)
        外键字段:添加外键约束的字段
        外键值:外键字段中的每一个值
        --------
        设计数据库表,用来维护学生和班级的信息?
            第一种方案:一张表存储所有的数据
                no(pk)   name   classno     classname
                --------------------------------------
                  1       zs1     101        北京市大兴区经济技术开发区亦庄二中高三1班
                  2       zs2     102        北京市大兴区经济技术开发区亦庄二中高三2班
            缺点:冗余
            第二种方案:两张表
                t_class  班级表
                cno(pk)    cname
                -----------------------
                101        北京市大兴区经济技术开发区亦庄二中高三1班
                102        北京市大兴区经济技术开发区亦庄二中高三2班
                
                t_student 学生表
                sno(pk)    sname     classno(该字段添加外键约束后,数值只能是班级表中的cno中存在的数值)
                ------------------------
                  1         zs1      10x
                  2         zs2      10y
            t_student中的classno字段引用t_class表中的cno字段,此时t_student表叫做字表,t_class表叫作父表.
            
            删除表的时候,先删除字表,再删除父表
            创建表的时候,先创建父表,再创建字表
            create table t_class(
                cno int,
                cname varchar(255),
                primary key(cno)
            );
            create table t_student(
                sno int,
                sname varchar(255),
                classno int,
                primary key(sno),
                foreign key(classno) reference t_class(cno)
            );      
        --------
        外键值可以为NULL
        外键字段,被引用字段必须是主键吗?不一定是主键,但至少具有unique约束
        
存储引擎(了解)
    即数据在MySQL中的存储方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值