1、sql、DB、DBMS分别是什么,他们之间的关系?

  • DB:DataBase(数据库,数据库实际上在硬盘上以文件的形式存在)
  • DBMS: DataBase Management System(数据库管理系统,常见的有:MySQL、Oracle、DB2、Sybase 、SqlServer…)
  • SQL:
    • 结构化查询语言,是一门标准通用的语言。标准的sql适合于所有的数据库产品。
    • SQL属于高级语言。只要能看懂英语单词的,写出来的sql语句,就可以读懂什么意思。
    • SQL语句在执行的时候,实际上内部也会先进行编译,然后再执行sql(sql语句的编译由DBMS完成
  • DBMS负责执行sql语句,通过执行sql语句来操作DB当中的数据
  • DBMS -(执行)-> SQL -(操作)-> DB

**

2、什么是表?

  • 表:table
  • table是数据库的基本组成单元,所有的数据都以表格的形式组织,目的是可读性强。
  • 一个表包括行和列:

    • 行:被称为数据/记录(data)
    • 列:被称为字段(column) | 学号(int) | 姓名(varchar) | 年龄(int) | | —- | —- | —- | | 110 | 张三 | 20 | | 120 | 李四 | 21 |
  • 每一个字段应该包括哪些属性?字段名、数据类型、相关的约束

3、SQL语句怎么分类?

  • 学习MySQL主要还是学习通用的SQL语句,SQL语句包括增删改查
  • SQL语句分类
    • DQL(数据查询语言): 查询语句,凡是select语句都是DQL。
    • DML(数据操作语言):insert delete update,对表当中的数据进行增删改。
    • DDL(数据定义语言):create drop alter,对表结构的增删改。
    • TCL(事务控制语言):commit提交事务,rollback回滚事务。(TCL中的T是Transaction)
    • DCL(数据控制语言): grant授权、revoke撤销权限等。

4、导入数据(练习使用)

  1. 登录mysql数据库管理系统
    • dos命令窗口输入:mysql -uroot -pXXX(root为账号,XXX为安装mysql时配置的密码)
  2. 查看有哪些数据库

    • show databases; (这个不是SQL语句,属于MySQL的命令)
      1. +--------------------+
      2. | Database |
      3. +--------------------+
      4. | information_schema |
      5. | mysql |
      6. | performance_schema |
      7. | test |
      8. +--------------------+
  3. 创建自己的数据库

    • create database bjpowernode; (这个不是SQL语句,属于MySQL的命令)
  4. 使用bjpowernode数据
    • use bjpowernode; (这个不是SQL语句,属于MySQL的命令)
  5. 查看当前使用的数据库中有哪些表?
    • show tables; (这个不是SQL语句,属于MySQL的命令)
  6. 初始化数据
    • source D:\course\05-MySQL\resources\bjpowernode.sql (source后跟上资源路径)
    • 该数据脚本内容如下 ```sql DROP TABLE IF EXISTS EMP; DROP TABLE IF EXISTS DEPT; DROP TABLE IF EXISTS SALGRADE;

CREATE TABLE DEPT (DEPTNO int(2) not null , DNAME VARCHAR(14) , LOC VARCHAR(13), primary key (DEPTNO) ); CREATE TABLE EMP (EMPNO int(4) not null , ENAME VARCHAR(10), JOB VARCHAR(9), MGR INT(4), HIREDATE DATE DEFAULT NULL, SAL DOUBLE(7,2), COMM DOUBLE(7,2), primary key (EMPNO), DEPTNO INT(2) );

CREATE TABLE SALGRADE ( GRADE INT, LOSAL INT, HISAL INT );


7. 注意:数据初始化完成之后,有三张表:
```sql
    +-----------------------+
    | Tables_in_bjpowernode |
    +-----------------------+
    | dept                  |            部门表
    | emp                   |            员工表
    | salgrade              |            薪资等级表
    +-----------------------+

5、什么是sql脚本?

  • bjpowernode.sql,这个文件以sql结尾,这样的文件被称为“sql脚本”
  • 当一个文件的扩展名是“.sql”,并且该文件中编写了大量的sql语句,我们称这样的文件为sql脚本
  • 注意:直接使用source命令可以执行sql脚本
  • sql脚本中的数据量太大的时候,无法打开,这时就可以使用source命令完成初始化

6、删除数据库

  • drop database bjpowernode;

**

7、查看表结构

  • desc dept;

      +--------+-------------+------+-----+---------+-------+
      | Field  | Type        | Null | Key | Default | Extra |
      +--------+-------------+------+-----+---------+-------+
      | DEPTNO | int(2)      | NO   | PRI | NULL    |       |        部门编号
      | DNAME  | varchar(14) | YES  |     | NULL    |       |        部门名称
      | LOC    | varchar(13) | YES  |     | NULL    |       |        部门位置
      +--------+-------------+------+-----+---------+-------+
    
  • desc emp;

      +----------+-------------+------+-----+---------+-------+
      | Field    | Type        | Null | Key | Default | Extra |
      +----------+-------------+------+-----+---------+-------+
      | EMPNO    | int(4)      | NO   | PRI | NULL    |       |    员工编号
      | ENAME    | varchar(10) | YES  |     | NULL    |       |    员工姓名
      | JOB      | varchar(9)  | YES  |     | NULL    |       |    工作岗位
      | MGR      | int(4)      | YES  |     | NULL    |       |    上级领导编号
      | HIREDATE | date        | YES  |     | NULL    |       |    入职日期
      | SAL      | double(7,2) | YES  |     | NULL    |       |    月薪
      | COMM     | double(7,2) | YES  |     | NULL    |       |    补助/津贴
      | DEPTNO   | int(2)      | YES  |     | NULL    |       |    部门编号
      +----------+-------------+------+-----+---------+-------+
    
  • desc salgrade;

      +-------+---------+------+-----+---------+-------+
      | Field | Type    | Null | Key | Default | Extra |
      +-------+---------+------+-----+---------+-------+
      | GRADE | int(11) | YES  |     | NULL    |       |        等级
      | LOSAL | int(11) | YES  |     | NULL    |       |        最低薪资
      | HISAL | int(11) | YES  |     | NULL    |       |        最高薪资
      +-------+---------+------+-----+---------+-------+
    

8、查看表数据

  • select * from emp;

    +-------+--------+-----------+------+------------+---------+---------+--------+
    | EMPNO | ENAME  | JOB       | MGR  | HIREDATE   | SAL     | COMM    | DEPTNO |
    +-------+--------+-----------+------+------------+---------+---------+--------+
    |  7369 | SMITH  | CLERK     | 7902 | 1980-12-17 |  800.00 |    NULL |     20 |
    |  7499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 | 1600.00 |  300.00 |     30 |
    |  7521 | WARD   | SALESMAN  | 7698 | 1981-02-22 | 1250.00 |  500.00 |     30 |
    |  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975.00 |    NULL |     20 |
    |  7654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 | 1250.00 | 1400.00 |     30 |
    |  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 | 2850.00 |    NULL |     30 |
    |  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450.00 |    NULL |     10 |
    |  7788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 | 3000.00 |    NULL |     20 |
    |  7839 | KING   | PRESIDENT | NULL | 1981-11-17 | 5000.00 |    NULL |     10 |
    |  7844 | TURNER | SALESMAN  | 7698 | 1981-09-08 | 1500.00 |    0.00 |     30 |
    |  7876 | ADAMS  | CLERK     | 7788 | 1987-05-23 | 1100.00 |    NULL |     20 |
    |  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 |  950.00 |    NULL |     30 |
    |  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 | 3000.00 |    NULL |     20 |
    |  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300.00 |    NULL |     10 |
    +-------+--------+-----------+------+------------+---------+---------+--------+
    
  • select * from dept;

    +--------+------------+----------+
    | DEPTNO | DNAME      | LOC      |
    +--------+------------+----------+
    |     10 | ACCOUNTING | NEW YORK |
    |     20 | RESEARCH   | DALLAS   |
    |     30 | SALES      | CHICAGO  |
    |     40 | OPERATIONS | BOSTON   |
    +--------+------------+----------+
    
  • select * from salgrade;

    +-------+-------+-------+
    | GRADE | LOSAL | HISAL |
    +-------+-------+-------+
    |     1 |   700 |  1200 |
    |     2 |  1201 |  1400 |
    |     3 |  1401 |  2000 |
    |     4 |  2001 |  3000 |
    |     5 |  3001 |  9999 |
    +-------+-------+-------+
    

9、常用命令?

  • select database(); 查看当前使用的是哪个数据库
  • select version(); 查看mysql的版本号
  • \c,结束一条语句
  • exit 命令,退出mysql
  • show create table emp;查看创建表的语句(该句意思为查看emp表的创建语句)

11、简单的查询语句(DQL)


  • 语法格式:select 字段名1,字段名2,字段名3,…. from 表名;
  • 提示:
    1. 任何一条sql语句都以“;”结尾
    2. sql语句不区分大小写
  • 查询员工的年薪?(字段可以参与数学运算

    select ename,sal * 12 from emp;
          +--------+----------+
          | ename  | sal * 12 |
          +--------+----------+
          | SMITH  |  9600.00 |
          | ALLEN  | 19200.00 |
          | WARD   | 15000.00 |
          | JONES  | 35700.00 |
          | MARTIN | 15000.00 |
          | BLAKE  | 34200.00 |
          | CLARK  | 29400.00 |
          | SCOTT  | 36000.00 |
          | KING   | 60000.00 |
          | TURNER | 18000.00 |
          | ADAMS  | 13200.00 |
          | JAMES  | 11400.00 |
          | FORD   | 36000.00 |
          | MILLER | 15600.00 |
          +--------+----------+
    
  • 给查询结果的列重命名?

    select ename,sal*12 as yearsal from emp;
    +--------+----------+
    | ename  | yearsal  |
    +--------+----------+
    | SMITH  |  9600.00 |
    | ALLEN  | 19200.00 |
    | WARD   | 15000.00 |
    | JONES  | 35700.00 |
    | MARTIN | 15000.00 |
    | BLAKE  | 34200.00 |
    | CLARK  | 29400.00 |
    | SCOTT  | 36000.00 |
    | KING   | 60000.00 |
    | TURNER | 18000.00 |
    | ADAMS  | 13200.00 |
    | JAMES  | 11400.00 |
    | FORD   | 36000.00 |
    | MILLER | 15600.00 |
    +--------+----------+
    
  • 别名中有中文?

    • select ename,sal * 12 as 年薪 from emp; // 错误,中文该加单引号
    • 注意:标准sql语句中要求字符串使用单引号括起来。虽然mysql支持双引号,尽量别用。
      select ename,sal * 12 as '年薪' from emp;
      +--------+----------+
      | ename  | 年薪     |
      +--------+----------+
      | SMITH  |  9600.00 |
      | ALLEN  | 19200.00 |
      | WARD   | 15000.00 |
      | JONES  | 35700.00 |
      | MARTIN | 15000.00 |
      | BLAKE  | 34200.00 |
      | CLARK  | 29400.00 |
      | SCOTT  | 36000.00 |
      | KING   | 60000.00 |
      | TURNER | 18000.00 |
      | ADAMS  | 13200.00 |
      | JAMES  | 11400.00 |
      | FORD   | 36000.00 |
      | MILLER | 15600.00 |
      +--------+----------+
      
  • as关键字可以省略

    select empno,ename,sal*12 yearsal from emp;
    +-------+--------+----------+
    | empno | ename  | yearsal  |
    +-------+--------+----------+
    |  7369 | SMITH  |  9600.00 |
    |  7499 | ALLEN  | 19200.00 |
    |  7521 | WARD   | 15000.00 |
    |  7566 | JONES  | 35700.00 |
    |  7654 | MARTIN | 15000.00 |
    |  7698 | BLAKE  | 34200.00 |
    |  7782 | CLARK  | 29400.00 |
    |  7788 | SCOTT  | 36000.00 |
    |  7839 | KING   | 60000.00 |
    |  7844 | TURNER | 18000.00 |
    |  7876 | ADAMS  | 13200.00 |
    |  7900 | JAMES  | 11400.00 |
    |  7902 | FORD   | 36000.00 |
    |  7934 | MILLER | 15600.00 |
    +-------+--------+----------+
    
  • 查询所有字段

    • select * from emp; // 实际开发中不建议使用*,效率较低

12、条件查询

  • 语法格式:

select
字段,字段…
from
表名
where
条件;

  • 执行顺序:先from,然后where,最后select
  • 查询工资等于5000的员工姓名?

    select ename from emp where sal=5000;
    +-------+
    | ename |
    +-------+
    | KING  |
    +-------+
    
  • 查询SMITH的工资?(字符串使用单引号括起来)

    select sal from emp where ename='SMITH';
    +--------+
    | sal    |
    +--------+
    | 800.00 |
    +--------+
    
  • 找出工资高于/大于等于/小于/小于等于/不等于3000的员工 ```sql select ename,sal from emp where sal > 3000; select ename,sal from emp where sal >= 3000; select ename,sal from emp where sal < 3000; select ename,sal from emp where sal <= 3000;

select ename,sal from emp where sal <> 3000; select ename,sal from emp where sal != 3000;


- 找出工资在1100和3000之间的员工,包括1100和3000
```sql
select ename,sal from emp where sal >= 1100 and sal <= 3000;
-- between...and...是闭区间 [1100 ~ 3000]
select ename,sal from emp where sal between 1100 and 3000; 

-- between and在使用的时候必须左小右大,以下语句查询不到任何数据
select ename,sal from emp where sal between 3000 and 1100;

-- between and除了可以使用在数字方面之外,还可以使用在字符串方面,左闭右开
select ename from emp where ename between 'A' and 'C';
+-------+
| ename |
+-------+
| ALLEN |
| BLAKE |
| ADAMS |
+-------+
  • 找出哪些人津贴为NULL/不为NULL
  • 在数据库当中NULL不是一个值,代表什么也没有,为空。
  • 空不是一个值,不能用等号衡量。
  • 必须使用 is null或者is not null

    --津贴为NULL
    select ename,sal,comm from emp where comm is null;
    +--------+---------+------+
    | ename  | sal     | comm |
    +--------+---------+------+
    | SMITH  |  800.00 | NULL |
    | JONES  | 2975.00 | NULL |
    | BLAKE  | 2850.00 | NULL |
    | CLARK  | 2450.00 | NULL |
    | SCOTT  | 3000.00 | NULL |
    | KING   | 5000.00 | NULL |
    | ADAMS  | 1100.00 | NULL |
    | JAMES  |  950.00 | NULL |
    | FORD   | 3000.00 | NULL |
    | MILLER | 1300.00 | NULL |
    +--------+---------+------+
    -- 津贴不为NULL
    select ename,sal,comm from emp where comm is not null;
    +--------+---------+---------+
    | ename  | sal     | comm    |
    +--------+---------+---------+
    | ALLEN  | 1600.00 |  300.00 |
    | WARD   | 1250.00 |  500.00 |
    | MARTIN | 1250.00 | 1400.00 |
    | TURNER | 1500.00 |    0.00 |
    +--------+---------+---------+
    -- 找出哪些人没有津贴
    select ename,sal,comm from emp where comm is null or comm = 0;
    +--------+---------+------+
    | ename  | sal     | comm |
    +--------+---------+------+
    | SMITH  |  800.00 | NULL |
    | JONES  | 2975.00 | NULL |
    | BLAKE  | 2850.00 | NULL |
    | CLARK  | 2450.00 | NULL |
    | SCOTT  | 3000.00 | NULL |
    | KING   | 5000.00 | NULL |
    | TURNER | 1500.00 | 0.00 |
    | ADAMS  | 1100.00 | NULL |
    | JAMES  |  950.00 | NULL |
    | FORD   | 3000.00 | NULL |
    | MILLER | 1300.00 | NULL |
    +--------+---------+------+
    /*
    不可这样写
    select ename,sal,comm from emp where comm = null;
    */
    
  • 找出工作岗位是MANAGER和SALESMAN的员工

    select ename,job from emp where job = 'MANAGER' or job = 'SALESMAN';
    +--------+----------+
    | ename  | job      |
    +--------+----------+
    | ALLEN  | SALESMAN |
    | WARD   | SALESMAN |
    | JONES  | MANAGER  |
    | MARTIN | SALESMAN |
    | BLAKE  | MANAGER  |
    | CLARK  | MANAGER  |
    | TURNER | SALESMAN |
    +--------+----------+
    
  • and和or联合起来用:找出薪资大于1000的并且部门编号是20或30部门的员工。

    -- 错误的
    select ename,sal,deptno from emp where sal > 1000 and deptno = 20 or deptno = 30; 
    -- 正确的
    select ename,sal,deptno from emp where sal > 1000 and (deptno = 20 or deptno = 30); 
    -- 注意:当运算符的优先级不确定的时候加小括号。
    
  • in等同于or:找出工作岗位是MANAGER和SALESMAN的员工

    select ename,job from emp where job = 'SALESMAN' or job = 'MANAGER';
    select ename,job from emp where job in('SALESMAN', 'MANAGER');
    -- in后面的值不是区间,是具体的值
    -- not in: 不在这几个值当中,查询薪资不是800和5000的员工
    select ename,job from emp where sal not in(800, 5000);
    +--------+----------+
    | ename  | job      |
    +--------+----------+
    | ALLEN  | SALESMAN |
    | WARD   | SALESMAN |
    | JONES  | MANAGER  |
    | MARTIN | SALESMAN |
    | BLAKE  | MANAGER  |
    | CLARK  | MANAGER  |
    | SCOTT  | ANALYST  |
    | TURNER | SALESMAN |
    | ADAMS  | CLERK    |
    | JAMES  | CLERK    |
    | FORD   | ANALYST  |
    | MILLER | CLERK    |
    +--------+----------+
    
  • 模糊查询like

    • 在模糊查询当中,必须掌握两个特殊的符号,一个是%,一个是_
    • %代表任意多个字符,_代表任意1个字符
      -- 找出名字当中含有O的
      select ename from emp where ename like '%O%';
      +-------+
      | ename |
      +-------+
      | JONES |
      | SCOTT |
      | FORD  |
      +-------+
      -- 找出名字中第二个字母是A的?
      select ename from emp where ename like '_A%';
      +--------+
      | ename  |
      +--------+
      | WARD   |
      | MARTIN |
      | JAMES  |
      +--------+
      -- 找出名字中有下划线的,此处可以用'\'转型
      select name from t_user where name like '%\_%';
      --找出名字中最后一个字母是T的
      select ename from emp where ename like '%T';
      +-------+
      | ename |
      +-------+
      | SCOTT |
      +-------+
      

      13、排序(升序、降序)


  • 格式:

select
ename,sal
from
emp
order by
sal;

  • 按照工资升序,找出员工名和薪资

    select ename,sal from emp order by sal;
    +--------+---------+
    | ename  | sal     |
    +--------+---------+
    | SMITH  |  800.00 |
    | JAMES  |  950.00 |
    | ADAMS  | 1100.00 |
    | WARD   | 1250.00 |
    | MARTIN | 1250.00 |
    | MILLER | 1300.00 |
    | TURNER | 1500.00 |
    | ALLEN  | 1600.00 |
    | CLARK  | 2450.00 |
    | BLAKE  | 2850.00 |
    | JONES  | 2975.00 |
    | FORD   | 3000.00 |
    | SCOTT  | 3000.00 |
    | KING   | 5000.00 |
    +--------+---------+
    
  • 注意:默认是升序。怎么指定升序或者降序呢?asc表示升序,desc表示降序

  • 按照工资的降序排列,当工资相同的时候再按照名字的升序排列

    • 注意:越靠前的字段越能起到主导作用。只有当前面的字段无法完成排序的时候,才会启用后面的字段。
      select ename,sal from emp order by sal desc , ename asc;
      
  • 找出工作岗位是SALESMAN的员工,并且要求按照薪资的降序排列

    select ename,job,sal from emp where job='SALESMAN' order by sal desc;
    +--------+----------+---------+
    | ename  | job      | sal     |
    +--------+----------+---------+
    | ALLEN  | SALESMAN | 1600.00 |
    | TURNER | SALESMAN | 1500.00 |
    | WARD   | SALESMAN | 1250.00 |
    | MARTIN | SALESMAN | 1250.00 |
    +--------+----------+---------+
    /*
    select 
          字段                        3
      from
          表名                        1
      where
          条件                        2
      order by
          ....                        4
    
      order by是最后执行的。
    */
    

14、分组函数(多行处理函数

  • count 计数
  • sum 求和
  • avg 平均值
  • max 最大值
  • min 最小值
  • 记住:所有的分组函数都是对“某一组”数据进行操作的

    -- 找出工资总和?
    select sum(sal) from emp;
    -- 找出最高工资?
    select max(sal) from emp;
    -- 找出最低工资?
    select min(sal) from emp;
    -- 找出平均工资?
    select avg(sal) from emp;
    -- 找出总人数?
    select count(*) from emp;
    select count(ename) from emp;
    
  • 分组函数一共5个

  • 分组函数还有另一个名字:多行处理函数
  • 多行处理函数的特点:输入多行,最终输出的结果是1行
  • 重点:分组函数自动忽略NULL

    -- 查询员工津贴总和
    select sum(comm) from emp;
    +-----------+
    | sum(comm) |
    +-----------+
    |   2200.00 |
    +-----------+
    -- 千万不要像下面这样写,不需要额外添加‘where comm is not null’这个过滤条件。
    -- sum函数自动忽略NULL。
    select sum(comm) from emp where comm is not null;
    
  • 找出工资高于平均工资的员工

  • SQL语句当中有一个语法规则,分组函数不可直接使用在where子句当中
  • 因为group by是在where执行之后才会执行的,而分组函数要在group by之后执行,不能插队啊! ```sql — ERROR 1111 (HY000): Invalid use of group function — 无效的使用了分组函数 — 原因:SQL语句当中有一个语法规则,分组函数不可直接使用在where子句当中 — 因为group by是在where执行之后才会执行的 /* select 5
      ..            
    
    from 1
      ..
    
    where 2
      ..
    
    group by 3
      ..
    
    having 4
      ..
    
    order by 6
      ..
    
    */ select ename,sal from emp where sal > avg(sal);

— 正确写法如下 — 第一步:找出平均工资 select avg(sal) from emp; +——————-+ | avg(sal) | +——————-+ | 2073.214286 | +——————-+ — 第二步:找出高于平均工资的员工 select ename,sal from emp where sal > 2073.214286; +———-+————-+ | ename | sal | +———-+————-+ | JONES | 2975.00 | | BLAKE | 2850.00 | | CLARK | 2450.00 | | SCOTT | 3000.00 | | KING | 5000.00 | | FORD | 3000.00 | +———-+————-+ — 也可以这样写 select ename,sal from emp where sal > (select avg(sal) from emp);


- **count(*)**和**count(具体的某个字段)**,他们有什么区别?
   - **count(***):不是统计某个字段中数据的个数,而是统计总记录条数。(和某个字段无关)
   - **count(comm)**:表示统计comm字段中**不为NULL**的数据总数量。
```sql
select count(*) from emp;
+----------+
| count(*) |
+----------+
|       14 |
+----------+

select count(comm) from emp;
+-------------+
| count(comm) |
+-------------+
|           4 |
+-------------+
  • 分组函数也能组合起来用 ```sql select count(),sum(sal),avg(sal),max(sal),min(sal) from emp; +—————+—————+——————-+—————+—————+ | count() | sum(sal) | avg(sal) | max(sal) | min(sal) | +—————+—————+——————-+—————+—————+ | 14 | 29025.00 | 2073.214286 | 5000.00 | 800.00 | +—————+—————+——————-+—————+—————+

<a name="bYkTb"></a>
### 15、单行处理函数

- 什么是单行处理函数?
   - **输入一行,输出一行**。
- 计算每个员工的年薪
   - **重点:所有数据库都是这样规定的,只要有NULL参与的运算结果一定是NULL**
```sql
-- 像下面这样写是错误的
-- 所有数据库都是这样规定的,只要有NULL参与的运算结果一定是NULL
select ename,(sal+comm)*12 as yearsal from emp;

-- 正确写法,使用ifnull函数
select ename,(sal+ifnull(comm,0))*12 as yearsal from emp;
+--------+----------+
| ename  | yearsal  |
+--------+----------+
| SMITH  |  9600.00 |
| ALLEN  | 22800.00 |
| WARD   | 21000.00 |
| JONES  | 35700.00 |
| MARTIN | 31800.00 |
| BLAKE  | 34200.00 |
| CLARK  | 29400.00 |
| SCOTT  | 36000.00 |
| KING   | 60000.00 |
| TURNER | 18000.00 |
| ADAMS  | 13200.00 |
| JAMES  | 11400.00 |
| FORD   | 36000.00 |
| MILLER | 15600.00 |
+--------+----------+
  • ifnull() 空处理函数
    • ifnull(可能为NULL的数据,被当做什么处理) : 属于单行处理函数
      -- 查询每个员工的津贴,若为null则当作0处理
      select ename,ifnull(comm,0) as comm from emp;
      +--------+---------+
      | ename  | comm    |
      +--------+---------+
      | SMITH  |    0.00 |
      | ALLEN  |  300.00 |
      | WARD   |  500.00 |
      | JONES  |    0.00 |
      | MARTIN | 1400.00 |
      | BLAKE  |    0.00 |
      | CLARK  |    0.00 |
      | SCOTT  |    0.00 |
      | KING   |    0.00 |
      | TURNER |    0.00 |
      | ADAMS  |    0.00 |
      | JAMES  |    0.00 |
      | FORD   |    0.00 |
      | MILLER |    0.00 |
      +--------+---------+
      

16、group by 和 having

  • group by : 按照某个字段或者某些字段进行分组。
  • having : 对分组之后的数据进行再次过滤。
  • 找出每个工作岗位的最高薪资

    select max(sal),job from emp group by job;
    +----------+-----------+
    | max(sal) | job       |
    +----------+-----------+
    |  3000.00 | ANALYST   |
    |  1300.00 | CLERK     |
    |  2975.00 | MANAGER   |
    |  5000.00 | PRESIDENT |
    |  1600.00 | SALESMAN  |
    +----------+-----------+
    
  • 注意:分组函数一般都会和group by联合使用,这也是为什么它被称为分组函数的原因

  • 任何一个分组函数(count sum avg max min)都是在group by语句执行结束之后才会执行的
  • 当一条sql语句没有group by的话,整张表的数据会自成一组
  • 记住一个规则:当一条语句中有group by的话,select后面只能跟分组函数和参与分组的字段

    -- 像下面这样写在mysql中虽然有结果,但是毫无意义,而在oracle中直接报错
    -- Oracle的语法规则比MySQL语法规则严谨
    -- 当一条语句中有group by的话,select后面只能跟分组函数和参与分组的字段
    select ename,max(sal),job from emp group by job;
    
  • 多个字段能不能联合起来一块分组?

    -- 找出每个部门不同工作岗位的最高薪资
    select deptno,job,max(sal) from emp group by deptno,job;
    +--------+-----------+----------+
    | deptno | job       | max(sal) |
    +--------+-----------+----------+
    |     10 | CLERK     |  1300.00 |
    |     10 | MANAGER   |  2450.00 |
    |     10 | PRESIDENT |  5000.00 |
    |     20 | ANALYST   |  3000.00 |
    |     20 | CLERK     |  1100.00 |
    |     20 | MANAGER   |  2975.00 |
    |     30 | CLERK     |   950.00 |
    |     30 | MANAGER   |  2850.00 |
    |     30 | SALESMAN  |  1600.00 |
    +--------+-----------+----------+
    
  • 找出每个部门的最高薪资,要求显示薪资大于2900的数据

    • 建议能够使用where先过滤掉的就尽量使用where,不行再使用having ```sql — 第一步:找出每个部门的最高薪资 select max(sal),deptno from emp group by deptno; +—————+————+ | max(sal) | deptno | +—————+————+ | 5000.00 | 10 | | 3000.00 | 20 | | 2850.00 | 30 | +—————+————+ — 第二步:找出薪资大于2900 — 这种方式效率低。 select max(sal),deptno from emp group by deptno having max(sal) > 2900; +—————+————+ | max(sal) | deptno | +—————+————+ | 5000.00 | 10 | | 3000.00 | 20 | +—————+————+

— 效率较高,建议能够使用where过滤的尽量使用where。 select max(sal),deptno from emp where sal > 2900 group by deptno;
+—————+————+ | max(sal) | deptno | +—————+————+ | 5000.00 | 10 | | 3000.00 | 20 | +—————+————+ ```

17、总结一个完整的DQL语句怎么写?

  • 顺序:

select 5
..
from 1
..
where 2
..
group by 3
..
having 4
..
order by 6
..