Mysql基础

Mysql基础

基本操作

导入sql文件

在进入到mysql数据库中后,使用命令

source + sql文件的路径;

就可以将sql文件导入到数据库中。

查看数据库表结构
desc + 表名

查看版本号

select version();

查看当前使用的数据库

select database();

终止一条命令

\c

DQL

简单查询
select loc from dept;
select deptno,dname from dpet;

查询表中所有字段

1.select * from dept;  这种查询会先将*转化为表中所有字段,效率上来说会稍微低一点,可读性也差
2.select 表中所有字段 from dept; 推荐使用第二种

给查询列起别名–as

select deptno,dname as deptname from dept;
只是将显示的查询结果列显示为deptname,原表不会发生改变。

取的别名有空格的话,可以用‘’包裹起来
select deptno,dname 'dept name' from dept;
select deptno,dname "dept name" from dept;
在所有的数据库中,字符串统一用单引号括起来,mysql支持双引号,oracle不支持双引号

计算员工工资

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 |
+--------+----------+


mysql> 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 |
+--------+----------+

如果别名是中文,需要使用单引号括起来
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 |
+--------+----------+
条件查询

= 、<、>、!= <= 、>= 、is null条件

mysql> select ename,empno from emp where sal = 800;
+-------+-------+
| ename | empno |
+-------+-------+
| SMITH |  7369 |
+-------+-------+
1 row in set (0.00 sec)

mysql> select ename,empno from emp where sal != 800;
mysql> select ename,empno from emp where sal <> 800;  <>相当于不等
+--------+-------+
| ename  | empno |
+--------+-------+
| ALLEN  |  7499 |
| WARD   |  7521 |
| JONES  |  7566 |
| MARTIN |  7654 |
| BLAKE  |  7698 |
| CLARK  |  7782 |
| SCOTT  |  7788 |
| KING   |  7839 |
| TURNER |  7844 |
| ADAMS  |  7876 |
| JAMES  |  7900 |
| FORD   |  7902 |
| MILLER |  7934 |
+--------+-------+

范围查询
mysql> select empno,ename,sal from emp where sal >= 2450 and sal <= 3000;
+-------+-------+---------+
| empno | ename | sal     |
+-------+-------+---------+
|  7566 | JONES | 2975.00 |
|  7698 | BLAKE | 2850.00 |
|  7782 | CLARK | 2450.00 |
|  7788 | SCOTT | 3000.00 |
|  7902 | FORD  | 3000.00 |
+-------+-------+---------+
between and 必须遵循左小右大的原则,范围相当于[2450,3000]闭区间
mysql> select empno,ename,sal from emp where sal between 2450 and 3000;
+-------+-------+---------+
| empno | ename | sal     |
+-------+-------+---------+
|  7566 | JONES | 2975.00 |
|  7698 | BLAKE | 2850.00 |
|  7782 | CLARK | 2450.00 |
|  7788 | SCOTT | 3000.00 |
|  7902 | FORD  | 3000.00 |
+-------+-------+---------+
5 rows in set (0.00 sec)

查询是否为空

mysql> select empno,ename,sal,comm from emp where comm is null;
mysql> select empno,ename,sal,comm from emp where comm is not null;
数据库中null不能使用=来判断,null在数据库中是真正意义的空,什么也没有。
+-------+--------+---------+------+
| empno | ename  | sal     | comm |
+-------+--------+---------+------+
|  7369 | SMITH  |  800.00 | NULL |
|  7566 | JONES  | 2975.00 | NULL |
|  7698 | BLAKE  | 2850.00 | NULL |
|  7782 | CLARK  | 2450.00 | NULL |
|  7788 | SCOTT  | 3000.00 | NULL |
|  7839 | KING   | 5000.00 | NULL |
|  7876 | ADAMS  | 1100.00 | NULL |
|  7900 | JAMES  |  950.00 | NULL |
|  7902 | FORD   | 3000.00 | NULL |
|  7934 | MILLER | 1300.00 | NULL |
+-------+--------+---------+------+

and | or |in 查询

mysql> select empno,ename from emp where sal > 2500 and job='manager';
+-------+-------+
| empno | ename |
+-------+-------+
|  7566 | JONES |
|  7698 | BLAKE |
+-------+-------+

mysql> select empno,ename,sal,comm from emp where comm is null or comm = 0;
+-------+--------+---------+------+
| empno | ename  | sal     | comm |
+-------+--------+---------+------+
|  7369 | SMITH  |  800.00 | NULL |
|  7566 | JONES  | 2975.00 | NULL |
|  7698 | BLAKE  | 2850.00 | NULL |
|  7782 | CLARK  | 2450.00 | NULL |
|  7788 | SCOTT  | 3000.00 | NULL |
|  7839 | KING   | 5000.00 | NULL |
|  7844 | TURNER | 1500.00 | 0.00 |
|  7876 | ADAMS  | 1100.00 | NULL |
|  7900 | JAMES  |  950.00 | NULL |
|  7902 | FORD   | 3000.00 | NULL |
|  7934 | MILLER | 1300.00 | NULL |
+-------+--------+---------+------+

and 优先级比 or优先级要高,会先执行and,所以在查询的时候可以通过加()表示准确的语意。
select * from emp where sal > 2500 and (deptno = 10 or deptno = 20);
+-------+-------+-----------+------+------------+---------+------+--------+
| EMPNO | ENAME | JOB       | MGR  | HIREDATE   | SAL     | COMM | DEPTNO |
+-------+-------+-----------+------+------------+---------+------+--------+
|  7566 | JONES | MANAGER   | 7839 | 1981-04-02 | 2975.00 | NULL |     20 |
|  7788 | SCOTT | ANALYST   | 7566 | 1987-04-19 | 3000.00 | NULL |     20 |
|  7839 | KING  | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL |     10 |
|  7902 | FORD  | ANALYST   | 7566 | 1981-12-03 | 3000.00 | NULL |     20 |
+-------+-------+-----------+------+------------+---------+------+--------+

in 是包含,相当于多个or(not in表示不在这个集合里面)

select empno,ename,job from emp where job in('manager','salesman');
in后面跟的是一个集合
+-------+--------+----------+
| empno | ename  | job      |
+-------+--------+----------+
|  7499 | ALLEN  | SALESMAN |
|  7521 | WARD   | SALESMAN |
|  7566 | JONES  | MANAGER  |
|  7654 | MARTIN | SALESMAN |
|  7698 | BLAKE  | MANAGER  |
|  7782 | CLARK  | MANAGER  |
|  7844 | TURNER | SALESMAN |
+-------+--------+----------+
模糊查询

like %匹配任意多个字符 下划线代表任意一个字符

select ename from emp where ename like '%o%';
找出名字中含有'o'的名字

找出以t结尾
select ename from emp where ename like '%t';

找出以k开头
select ename from emp where ename like 'k%';

第二个字母为a的
select ename from emp where ename like '_a%';
第三个字母为r的
select ename from emp where ename like '__a%';

找出名字中有下划线的
select ename from emp where ename like '%\_%';
排序

查询所有员工的工资排序

mysql> select ename,sal from emp order by sal; 默认是升序
select ename,sal from emp order by sal asc;升序
+--------+---------+
| 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 |
| SCOTT  | 3000.00 |
| FORD   | 3000.00 |
| KING   | 5000.00 |
+--------+---------+

mysql> select ename,sal from emp order by sal desc; 降序需要加descend
+--------+---------+
| ename  | sal     |
+--------+---------+
| KING   | 5000.00 |
| SCOTT  | 3000.00 |
| FORD   | 3000.00 |
| JONES  | 2975.00 |
| BLAKE  | 2850.00 |
| CLARK  | 2450.00 |
| ALLEN  | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
| WARD   | 1250.00 |
| MARTIN | 1250.00 |
| ADAMS  | 1100.00 |
| JAMES  |  950.00 |
| SMITH  |  800.00 |
+--------+---------+

按照多个字段排序
查询员工名字和薪资,按照薪资升序排列,如果薪资一样的话,按照名字升序排列。
mysql> select ename,sal from emp order by sal asc,ename asc;
+--------+---------+
| ename  | sal     |
+--------+---------+
| SMITH  |  800.00 |
| JAMES  |  950.00 |
| ADAMS  | 1100.00 |
| MARTIN | 1250.00 |
| WARD   | 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 |
+--------+---------+

根据字段的位置排序
select ename,sal from emp order by 2;按照查询结果的第二列排序,不推荐,不健壮
mysql> select ename,sal from emp where sal between 1250 and 3000 order by sal desc;
执行顺序 :
1.from 
2.where
3.select
4.order by
+--------+---------+
| ename  | sal     |
+--------+---------+
| SCOTT  | 3000.00 |
| FORD   | 3000.00 |
| JONES  | 2975.00 |
| BLAKE  | 2850.00 |
| CLARK  | 2450.00 |
| ALLEN  | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
| WARD   | 1250.00 |
| MARTIN | 1250.00 |
+--------+---------+

数据处理函数

upper、lower 转换大小写
select lower(ename) from emp;
select upper(ename) from emp;

奇怪的bug

select后面跟字面量 会创建n个字面量,n为emp的记录
mysql> select upper('2'+ lower(ename)) from emp;
+--------------------------+
| upper('2'+ lower(ename)) |
+--------------------------+
| 2                        |
| 2                        |
| 2                        |
| 2                        |
| 2                        |
| 2                        |
| 2                        |
| 2                        |
| 2                        |
| 2                        |
| 2                        |
| 2                        |
| 2                        |
| 2                        |
+--------------------------+
以上bug是mysql中字符串拼接不能用+号,用的是一个concat函数
mysql> select concat(2,upper(lower(ename))) from emp;
+-------------------------------+
| concat(2,upper(lower(ename))) |
+-------------------------------+
| 2SMITH                        |
| 2ALLEN                        |
| 2WARD                         |
| 2JONES                        |
| 2MARTIN                       |
| 2BLAKE                        |
| 2CLARK                        |
| 2SCOTT                        |
| 2KING                         |
| 2TURNER                       |
| 2ADAMS                        |
| 2JAMES                        |
| 2FORD                         |
| 2MILLER                       |
+-------------------------------+
substr 取字串
select substr(ename,1,1) as ename from emp;
其实下标从1开始,没有0
字符串拼接
select concat(empno,ename) from emp;
首字母大写
select concat(upper(substr(ename,1,1)),lower(substr(ename,2,length(ename)-1))) result from emp;
获取字段长度
获取字符串长度
select length(ename) enamelength from emp;
去除空格
mysql> select * from emp where ename =  trim(' KING ');
+-------+-------+-----------+------+------------+---------+------+--------+
| EMPNO | ENAME | JOB       | MGR  | HIREDATE   | SAL     | COMM | DEPTNO |
+-------+-------+-----------+------+------------+---------+------+--------+
|  7839 | KING  | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL |     10 |
+-------+-------+-----------+------+------------+---------+------+--------+
仅能去除前后的空格,不能去除中间的空格

mysql> select * from emp where ename =  trim(' KI NG ');
Empty set (0.00 sec)
日期的处理

str_to_date

round 四舍五入
select round(1234.56,0) as result from emp;保留0位小数
select round(1234.56,1) as result from emp;保留1位小数
select round(1234.56,-1) as result from emp;保留到十位整数
生成随机数 rand
select round(rand()*100,0) as result from emp;
100以内的随机数
ifnull 可以将null转化为一个数值

在左右的数据库中,只要有null参与的数学运算,结果都是null

ifnull(数据,被当做哪一个值)

计算年薪 = (月薪 + 补助) * 12;
错误示范
mysql> select ename,(sal + comm) *12 as yearsal from emp;
+--------+----------+
| ename  | yearsal  |
+--------+----------+
| SMITH  |     NULL |
| ALLEN  | 22800.00 |
| WARD   | 21000.00 |
| JONES  |     NULL |
| MARTIN | 31800.00 |
| BLAKE  |     NULL |
| CLARK  |     NULL |
| SCOTT  |     NULL |
| KING   |     NULL |
| TURNER | 18000.00 |
| ADAMS  |     NULL |
| JAMES  |     NULL |
| FORD   |     NULL |
| MILLER |     NULL |
+--------+----------+


正确示范
mysql> 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 |
+--------+----------+
case when then when then else end
不修改数据库,仅将查询结果显示上调
select ename,job, sal,
	(case job 
	when 'MANAGER' then sal*1.1
	when 'SALESMAN' then sal*1.5
	else sal
	end)
	as newsal
from emp;

+--------+-----------+---------+---------+
| ename  | job       | sal     | newsal  |
+--------+-----------+---------+---------+
| SMITH  | CLERK     |  800.00 |  800.00 |
| ALLEN  | SALESMAN  | 1600.00 | 2400.00 |
| WARD   | SALESMAN  | 1250.00 | 1875.00 |
| JONES  | MANAGER   | 2975.00 | 3272.50 |
| MARTIN | SALESMAN  | 1250.00 | 1875.00 |
| BLAKE  | MANAGER   | 2850.00 | 3135.00 |
| CLARK  | MANAGER   | 2450.00 | 2695.00 |
| SCOTT  | ANALYST   | 3000.00 | 3000.00 |
| KING   | PRESIDENT | 5000.00 | 5000.00 |
| TURNER | SALESMAN  | 1500.00 | 2250.00 |
| ADAMS  | CLERK     | 1100.00 | 1100.00 |
| JAMES  | CLERK     |  950.00 |  950.00 |
| FORD   | ANALYST   | 3000.00 | 3000.00 |
| MILLER | CLERK     | 1300.00 | 1300.00 |
+--------+-----------+---------+---------+

分组函数/多行处理函数

分组函数是多个输入–>一个输出。分组函数使用时先分组才能使用,如果没有分组,则默认整张表为一组数据。

注意:

1.分组函数会自动忽略null,不需要提前对null处理

2.count会忽略null,不会将null统计进去

3.count(*)与count(具体字段)区别:

​ count(字段):表示统计该字段下不为null的元素的总和

​ count(*):表示多少行

4.分组函数不能直接使用在where子句中,分组函数在使用时必须先分组后再使用,where使用时还没分组

​ 找出比最低工资高的员工信息

错误示范
select ename,sal from emp where sal > min(sal);
报错1111!可恶
ERROR 1111 (HY000): Invalid use of group function

正确
select ename,sal from emp where sal > (select min(sal) from emp);
count 计数
select count(ename) from emp;
sum 求和
工资和
select sum(sal) from emp;
avg 求平均
select avg(sal) from emp;
max 取最大
工资最多为多少
select max(sal) from emp;
min 取最小
select min(sal) from emp;

分组查询

格式:
select
	
from

where

group by

order by

执行顺序:
1.from
2.where
3.group by
4.select
5.order by

查询每一个部门的工资和

mysql> select job,sum(sal) from emp group by job;
+-----------+----------+
| job       | sum(sal) |
+-----------+----------+
| CLERK     |  4150.00 |
| SALESMAN  |  5600.00 |
| MANAGER   |  8275.00 |
| ANALYST   |  6000.00 |
| PRESIDENT |  5000.00 |
+-----------+----------+

查询每一个部门的最大工资

select deptno,max(sal) as maxsal from emp group by deptno order by deptno;

查询每个部门不同岗位的最高薪资

mysql> select deptno,job,max(sal) as maxsal from emp group by deptno,job order by deptno;
+--------+-----------+---------+
| deptno | job       | maxsal  |
+--------+-----------+---------+
|     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 |
+--------+-----------+---------+
9 rows in set (0.00 sec)

查出每个部门最高薪资大于3000的部门

方法1:
mysql> select deptno,max(sal) from emp group by deptno
    -> having max(sal) > 3000;
+--------+----------+
| deptno | max(sal) |
+--------+----------+
|     10 |  5000.00 |
+--------+----------+
1 row in set (0.00 sec)
方法2:效率更高
mysql> select deptno,max(sal) from emp where sal > 3000 group by deptno;
+--------+----------+
| deptno | max(sal) |
+--------+----------+
|     10 |  5000.00 |
+--------+----------+

查询部门平均工资高于2500的

mysql> select deptno,avg(sal) from emp group by deptno having avg(sal) > 2500;
+--------+-------------+
| deptno | avg(sal)    |
+--------+-------------+
|     10 | 2916.666667 |
+--------+-------------+
总结:
select

from

where

group by 

having

order by;

执行顺序:
1.from
2.where
3.group by
4.having
5.select
6.order by	

distinct

去除查询出来的重复数据,原数据不受影响
mysql> select distinct job from emp;
+-----------+
| job       |
+-----------+
| CLERK     |
| SALESMAN  |
| MANAGER   |
| ANALYST   |
| PRESIDENT |
+-----------+

联合起来去除重复记录
mysql> select distinct job,deptno from emp;
+-----------+--------+
| job       | deptno |
+-----------+--------+
| CLERK     |     20 |
| SALESMAN  |     30 |
| MANAGER   |     20 |
| MANAGER   |     30 |
| MANAGER   |     10 |
| ANALYST   |     20 |
| PRESIDENT |     10 |
| CLERK     |     30 |
| CLERK     |     10 |
+-----------+--------+

连接查询

多张表联合起来查询数据。

连接查询的分类

根据表连接的方式分类:

​ 内连接

​ 等值连接

​ 非等值连接

​ 自连接

​ 外连接

​ 左连接

​ 右连接

​ 全连接

简单连接查询
select 
	ename,dname
from 
	emp,dept
where
	emp.deptno = dept.deptno;

+--------+------------+
| ename  | dname      |
+--------+------------+
| SMITH  | RESEARCH   |
| ALLEN  | SALES      |
| WARD   | SALES      |
| JONES  | RESEARCH   |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| CLARK  | ACCOUNTING |
| SCOTT  | RESEARCH   |
| KING   | ACCOUNTING |
| TURNER | SALES      |
| ADAMS  | RESEARCH   |
| JAMES  | SALES      |
| FORD   | RESEARCH   |
| MILLER | ACCOUNTING |
+--------+------------+

为了查询效率,做如下优化
1.select选择字段时,明确指出字段属于哪一张表,避免到两张表中去找
2.from时可以给表取别名,这样可以缩短代码长度(尤其是在表名特别长的时候)
sql92语法内连接
select 
	e.ename,d.dname
from 
	emp e,dept d;
where 
	e.deptno = d.deptno;
	

sql 99语法
select 
	e.ename,d.dname
from 
	emp e 
inner join 
	dept d 
on 
	e.deptno = d.deptno
where 
	substr(e.ename,1,1)='s' and d.dname like "%S%";

内连接
等值连接
sql 99语法
select 
	e.ename,d.dname
from 
	emp e 
inner join 
	dept d 
on 
	e.deptno = d.deptno
where 
	substr(e.ename,1,1)='s' and d.dname like "%S%";
非等值连接
select 
	e.ename,e.sal,s.grade
from
	emp e
inner join
	salgrade s
on
	e.sal between s.losal and s.hisal;
	
+--------+---------+-------+
| ename  | sal     | grade |
+--------+---------+-------+
| SMITH  |  800.00 |     1 |
| ALLEN  | 1600.00 |     3 |
| WARD   | 1250.00 |     2 |
| JONES  | 2975.00 |     4 |
| MARTIN | 1250.00 |     2 |
| BLAKE  | 2850.00 |     4 |
| CLARK  | 2450.00 |     4 |
| SCOTT  | 3000.00 |     4 |
| KING   | 5000.00 |     5 |
| TURNER | 1500.00 |     3 |
| ADAMS  | 1100.00 |     1 |
| JAMES  |  950.00 |     1 |
| FORD   | 3000.00 |     4 |
| MILLER | 1300.00 |     2 |
+--------+---------+-------+
自连接

查询员工的上级领导,要求显示员工名和对应的领导名

select
	a.ename ename,b.ename leadname
from
	emp a
join
	emp b
on
	a.empno = b.mgr
;

+-------+----------+
| ename | leadname |
+-------+----------+
| FORD  | SMITH    |
| BLAKE | ALLEN    |
| BLAKE | WARD     |
| KING  | JONES    |
| BLAKE | MARTIN   |
| KING  | BLAKE    |
| KING  | CLARK    |
| JONES | SCOTT    |
| BLAKE | TURNER   |
| SCOTT | ADAMS    |
| BLAKE | JAMES    |
| JONES | FORD     |
| CLARK | MILLER   |
+-------+----------+
没有king 因为king的领导编号为null,他是最大的领导。
需要外连接来查询
select e.ename ename,d.ename leadname
from emp e
right join
	emp d
on e.mgr = d.empno;

+--------+----------+
| ename  | leadname |
+--------+----------+
| SMITH  | FORD     |
| ALLEN  | BLAKE    |
| WARD   | BLAKE    |
| JONES  | KING     |
| MARTIN | BLAKE    |
| BLAKE  | KING     |
| CLARK  | KING     |
| SCOTT  | JONES    |
| KING   | NULL     |
| TURNER | BLAKE    |
| ADAMS  | SCOTT    |
| JAMES  | BLAKE    |
| FORD   | JONES    |
| MILLER | CLARK    |
+--------+----------+

查看每一个领导下面的员工
mysql> select d.ename leadername,e.ename ename
    -> from emp e
    -> right join emp d
    -> on e.mgr = d.empno
    -> order by e.mgr;
+------------+--------+
| leadername | ename  |
+------------+--------+
| SMITH      | NULL   |
| ALLEN      | NULL   |
| WARD       | NULL   |
| MARTIN     | NULL   |
| TURNER     | NULL   |
| ADAMS      | NULL   |
| JAMES      | NULL   |
| MILLER     | NULL   |
| JONES      | SCOTT  |
| JONES      | FORD   |
| BLAKE      | TURNER |
| BLAKE      | ALLEN  |
| BLAKE      | WARD   |
| BLAKE      | JAMES  |
| BLAKE      | MARTIN |
| CLARK      | MILLER |
| SCOTT      | ADAMS  |
| KING       | BLAKE  |
| KING       | CLARK  |
| KING       | JONES  |
| FORD       | SMITH  |
+------------+--------+
外连接

右外连接:表示将join关键字右边的这张表看成主表,主要是为了将这张表的数据全部查询出来,捎带着关联查询左边的表,在外连接当中,两张表连接,产生了主次关系。

左连接:就是join左边的表是主表,右边的表是次表

select e.ename,d.dname
from emp e 
right join dept d
on d.deptno = e.deptno;

任何一个左连接都有右连接写法!

多表联查之内外连接例题

找出每个员工的部门名称、薪资等级、上级领导

显示出员工名、领导名、部门、薪资、薪资等级

select e.ename '员工名',l.ename '领导名',d.dname,e.sal,g.grade
from emp e
join dept d
on e.deptno = d.deptno
join salgrade g
on e.sal between g.losal and g.hisal
left join emp l
on e.mgr = l.empno;

+--------+--------+------------+---------+-------+
| 员工名 | 领导名 | dname      | sal     | grade |
+--------+--------+------------+---------+-------+
| SMITH  | FORD   | RESEARCH   |  800.00 |     1 |
| ALLEN  | BLAKE  | SALES      | 1600.00 |     3 |
| WARD   | BLAKE  | SALES      | 1250.00 |     2 |
| JONES  | KING   | RESEARCH   | 2975.00 |     4 |
| MARTIN | BLAKE  | SALES      | 1250.00 |     2 |
| BLAKE  | KING   | SALES      | 2850.00 |     4 |
| CLARK  | KING   | ACCOUNTING | 2450.00 |     4 |
| SCOTT  | JONES  | RESEARCH   | 3000.00 |     4 |
| KING   | NULL   | ACCOUNTING | 5000.00 |     5 |
| TURNER | BLAKE  | SALES      | 1500.00 |     3 |
| ADAMS  | SCOTT  | RESEARCH   | 1100.00 |     1 |
| JAMES  | BLAKE  | SALES      |  950.00 |     1 |
| FORD   | JONES  | RESEARCH   | 3000.00 |     4 |
| MILLER | CLARK  | ACCOUNTING | 1300.00 |     2 |
+--------+--------+------------+---------+-------+

子查询

select中嵌套select

select
	(select)
from
	(select)
where
	(select)

查询比最低工资高的员工

select ename,sal from emp where sal > (select min(sal) from emp);

DML

快速复制表

create table emp2 as select * from emp;

将一个查询结果当做一张表新建。

create table mydata as select empno,ename from emp where job='MANAGER';

将查询结果插入到表中

create table dept_bak as select * from dept;
insert into dept_bak select * from dept;

快速删除表中数据

delete from dept_bak;
delete属于DML删除数据的原理:
删除数据后,数据占用的空间并不会释放,优点在于可以回滚rollback,可以理解为逻辑上删除,但是在硬盘上的存储空间不会释放。

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> delete from dept_bak;
Query OK, 8 rows affected (0.00 sec)

mysql> select * from dept_bak;
Empty set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.01 sec)

mysql> select *  from dept_bak;
+--------+------------+----------+
| DEPTNO | DNAME      | LOC      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
+--------+------------+----------+
8 rows in set (0.00 sec)

truncate语句删除(属于ddl)

物理删除,这种删除效率比较高,但是不支持回滚。
mysql> truncate table dept_bak;
Query OK, 0 rows affected (0.03 sec)

mysql> select * from dept_bak;
Empty set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from dept_bak;
Empty set (0.00 sec)

约束

创建表的时候,给表字段加上约束,保证整个表中的数据的完整性、有效性。

非空约束

not null;
用来标注一个字段不能为空

唯一约束

unique
整个表中该字段不能重复
两个字段联合起来唯一(表级约束)
drop table if exists t_vip
create table t_vip(
	id int,
	name varchar(255),
	email varchar(255)
	unique(name,email)
)

主键约束

primary key;
当一个字段同时被unique + not null约束时,在mysql中就是成了主键字段(oracle中不一样)
主键值是每一行的身份证号,没有主键表没有意义。
drop table if exists t_vip
create table t_vip(
id int primary key auto_increament,
	name varchar(255),
	email varchar(255)
);
	

复合主键
drop table if exists t_vip
create table t_vip(
	id int ,
	name varchar(255),
	email varchar(255),
	primary key(id,name)
);
实际开发中不建议使用复合主键

一个表中的主键约束只能有一个,不能添加两个。主键值一般都是定长的,建议使用int bigint char

外键约束

foreign key;
加上fk的字段的记录必须在另外一张表的出现.
外键的出现是为了解决数据冗余问题,避免重复的数据存储,造成空间上的浪费
用了外键约束以后表级关系存在父子关系,删除时先删除子表,再删除父表。创建时先创建父,再创建子表。
drop table if exists t_student;
drop table if exists t_class;

create table t_class(
	class_no int primary key,
	class_name varchar(255)
)

create table t_student(
	id int primary key,
	name varchar(255),
	class_no int,
	foreign key(class_no) references t_class(class_no)
)

被引用的字段必须具有唯一性,可以为空。

约束

创建表的时候,给表字段加上约束,保证整个表中的数据的完整性、有效性。

非空约束

not null;
用来标注一个字段不能为空

唯一约束

unique
整个表中该字段不能重复
两个字段联合起来唯一(表级约束)
drop table if exists t_vip
create table t_vip(
	id int,
	name varchar(255),
	email varchar(255)
	unique(name,email)
)

主键约束

primary key;
当一个字段同时被unique + not null约束时,在mysql中就是成了主键字段(oracle中不一样)
主键值是每一行的身份证号,没有主键表没有意义。
drop table if exists t_vip
create table t_vip(
id int primary key auto_increament,
	name varchar(255),
	email varchar(255)
);
	

复合主键
drop table if exists t_vip
create table t_vip(
	id int ,
	name varchar(255),
	email varchar(255),
	primary key(id,name)
);
实际开发中不建议使用复合主键

一个表中的主键约束只能有一个,不能添加两个。主键值一般都是定长的,建议使用int bigint char

外键约束

foreign key;
加上fk的字段的记录必须在另外一张表的出现.
外键的出现是为了解决数据冗余问题,避免重复的数据存储,造成空间上的浪费
用了外键约束以后表级关系存在父子关系,删除时先删除子表,再删除父表。创建时先创建父,再创建子表。
drop table if exists t_student;
drop table if exists t_class;

create table t_class(
	class_no int primary key,
	class_name varchar(255)
)

create table t_student(
	id int primary key,
	name varchar(255),
	class_no int,
	foreign key(class_no) references t_class(class_no)
)

被引用的字段必须具有唯一性,可以为空。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值