show databases; /*show all the databases*/
use ...; /*choose the database*/
show tables; /*show tables in the database*/
show tables from ...(another database name); /*show tables in another database*/
show create table ...(tablename); /*show the sql statements used to create the table*/
explain ...(任何SQL语句); /*查看sql语句的执行计划*/
select database(); /*show current databse you are using*/
select version(); /*show current version of MySQL*/
exit; /*exits MySQL*/
select ename,sal*12 as annualsalary from emp;
select ename,sal*12 as ’年薪‘ from emp;
/*shows the ename and sal column with all data in sal column multiplied with 12 from emp, the sal column heading is named as annualsalary when shown*/
结果 ->sal column 里面的数据都 * 12:
as 也可以省略:
mysql
select ename,sal*12 as ’年薪‘ from emp; /*still works*/
select ename from emp where sal = 5000; /*show the ename data of the employee who has salary equal to 5000 from the emp table*/
select sal from emp where ename = 'SMITH'; /*show the ename data of the employee who has the name SMITH from the emp table*/
the ename column is defined to be varchar type (字符串), hence has to use single quotes
find the name of employee who has salary not equal to 3000:
mysql
select ename from emp where sal<>3000;
/*selects the ename where sal is bigger of smaller than 3000, hence not equal to 3000*/
select ename from emp where sal ! = 3000;
select ename, sal from emp where sal> = 1000 and sal < = 3000;
select ename, sal where sal between 1100 and 3000;
/*"between...and..." is inclusive*/
/*"between...and..." 必须左小右大*/
select ename, sal, comm from emp where comm is null;
/*ename, sall and comm data correspondind to the employee who has null for comm*/
/*THIS DOES NOT INCLUDE 0 because 0 is not null*/
select ename, sal, comm from emp where comm is not null;
/*ename, sall and comm data correspondind to the employee who don't have null for comm*/
/*THIS DOES INCLUDE 0 because 0 is not null*/
0 是个值,只不过是 0。 Null 不是一个值。
所以去找哪些人没有津贴或者津贴为 0 的:
mysql
select ename, sal, comm from emp where comm is null or comm = 0;
select ename,sal,deptno from emp where sal>1000 and deptno=20 or deptno=30; /*错误示范!!! 这里会选薪资大于1000并且部门20号的员工,也会显示所有薪资的30号部门的员工*/
select ename,sal,deptno from emp where sal>1000 and (deptno=20 or deptno=30);/*正确示范*/
and takes priority before or,brackets take priority over all
select ename, job from emp where sal in(800,1000);
/*找出的数据对应的是sal=800和sal=1000,不是之间!!!*/
select ename from emp where job in('SALESMAN','MANAGER');
/*找出Manager和salesman*/
not in 就是不在这几个值当中:
mysql
select ename from emp where job is not in('SALESMAN','MANAGER');
/*找出不是Manager和salesman的*/
select ename, job, sal from emp where job=’ALESMAN’ order by sal desc;
执行顺序是:
先执行 from 部分
再执行 where 部分
再执行 select 部分
然后再执行 order by 部分
mysql
select ename, sal as salary from emp order by salary;/*可以执行*/
/*这里证明了select部分是比order by部分先执行了,因为只有select部分先执行然后进行了别名“as”,salary这个别名已经起好了,之后order by才会识别salary这个别名,不然不会工作*/
select count(ename) from emp; /*finds number of employees*/
select sum(sal) from emp; /*finds sum of salary*/
select avg(sal) from emp; /*finds average of salary*/
select max(sal) from emp; /*finds max of salary*/
select min(sal) from emp; /*finds min of salary*/
可以组合起来用:
mysql
select count(*), sum(sal), avg(sal), max(sal), min(sal) from emp;
select e.ename,e.sal,s.GRADE from emp e inner join salgrade s on e.sal between s.LOSAL and s.HISAL;
/*ALWAYS REMEMBER TO ADD (e.g.)"e" and "s" etc for each column used to indicate which table the columns belong to hence to improve efficiency and readibility*/
/*inner 可以省略*/
案例 -> 找出每一个员工的上级领导,并且可以也展示出 king (不像上面 inner join 那样不显示)
mysql
select e.ename as '员工', b.ename as '领导' from emp e left outer join emp b on e.mgr = b.empno;
这里使用 left join 就是左连接,这里会把左边这个 emp e 当做主表,主表当中的数据是无论如何都要查出来的,也就意味着 select 部分只要有 e.(字段名) 那这个字段中所有的数据就一定会显示出来 (按照主表 emp e 的样子),就算表的连接并没有匹配到。 而且副表没匹配上的那个数据会自动以 NULL 进行匹配。(也就是会显示 null)
当然,很明显,这个左连接也可以有右连接的写法:
mysql
select e.ename as '员工', b.ename as '领导' from emp b right outer join emp e on e.mgr = b.empno; /*改为right join,然后将emp e改到后面作为右表,这样子右连接跟之前都是一个道理*/
注意:outer 也可以省略!
但是 left 和 right 不可以,区分内连接和外连接靠 left 和 right 就足够了,所以 inner 和 outer 可以省略
mysql
select e.ename as '员工', b.ename as '领导' from emp e left join emp b on e.mgr = b.empno;
select e.ename as '员工', b.ename as '领导' from emp b right join emp e on e.mgr = b.empno;
实例 -> 找出哪个部门没有员工
mysql
select d.dname from emp e right join dept d on d.deptno=e.deptno where e.deptno is null;
有两张表 AB, 这两张表连接,A 表的第一行会跟 B 表的第一行,第二行,第。。。行匹配一直到 B 表结束。
接着 A 表的第二行也会进行同样的操作。 这里可以想象两张表的所有 columns 的在一起形成了一个大 table,然后 table 里就是 A 表第一行数据和 B 表第一行数据,A 表第一行数据和 B 表第二行数据,A 表第一行数据和 B 表第三行数据等。 这个匹配是必成的不管是用 where 还是内连接外连接,这就是笛卡尔积现象。
为了避免笛卡尔积现象 (虽说是避免但不管怎么样他还是已经匹配好了,我们能做的只是过滤不想要的数据),我们使用 where 或者内连接外连接来从已经匹配好的所有数据中过滤掉不想要的,这里过滤规则就是连接规则,可以是任何样子的 (等值,非等值,自连接的等值和非等值),自己决定。
这个过滤使用 where 和内外连接的 join 都一样的,只不过内外连接的 join 结构更清晰。
select e.ename, d.dname, s.GRADE from emp e join dept d on e.deptno = d.deptno join salgrade s on e.sal between s.LOSAL and s.HISAL;
语法: select … from A join B on … join C on …
多个表,会先将 A 表和 B 表匹配然后按照第一个 on 的连接规则来从匹配好的数据里过滤掉不想要的,然后这个过滤好的结果会和 C 表结合,然后再按照第二个 on 的连接规则来从这个匹配好的数据里过滤掉不想要的,最后按照 select 部分展示。 当然这里的 join 可以是任何的 join。
案例 -> 找出每一个员工的部门名称,工资等级以及上级领导:
mysql
select e.ename,d.dname,s.GRADE,b.ename from emp e left outer join emp b on e.mgr = b.empno join dept d on e.deptno=d.deptno join salgrade s on e.sal between s.LOSAL and s.HISAL;
注意这个 left outer join 必须给 emp b 用,因为要是不在这用 KING 就会被过滤掉 (像之前讲的那样),之后再 join 其他表肯定 KING 相对应的数据都不会再有。
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,然后就正常拿这张表进行操作,就用 t 代表这个表,然后之后把其他剩下的写完了就可以把 t 转换回去到做他的 select 语句 (记得最好把有分组函数是字段名的改掉换成别的不然不能用),然后这个 t 可以继续当这个表的别名。
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;
/*之前做法*/
select ename, job from emp where job in ('MANAGER','SALESMAN');
select ename, job from emp where job = 'MANAGER' or job ='SALESMAN';
/*使用UNION*/
select ename, job from emp where job = 'MANAGER' union select ename, job from emp where job = 'SALESMAN'
以上例子可能 union 用起来有些没必要,但有时比如说用两张不相关的表数据想一块显示那么 or 和 in 可能就不行,然后 union 却可以
mysql
select ename, sal from emp union select dname from dept; /*报错,两个的select语句最后显示的columns数量不相等*/
select ename, sal from emp order by sal desc limit 0,5;
/*这个前面负责降序排好然后limit从0(第一条数据)取五个就是结果*/
select ename, sal from emp order by sal desc limit 5;
/*这样也行,如果limit后面只填写一个数字,那么那个数字前面默认就是0,也就是从第一条数据开始*/
create table t_user(
id int,
username varchar(255) not null,
password varchar(255)
); /*creates table with the username column as with "not null" constrain*/
insert into t_user(id,password) values(1,`123`);
/*这里插入会报错*/
/*ERROR 1364 (HY000): Field 'username' doesn't have a default value*/
create table t_user(
id int,
username varchar(255),
primary key(id)
);
跟上方方式结果一样
MySQL 提供的主键值自增:
mysql
create table t_user(
id int primary key auto_increment,/*让这个主键字段自增*/
username varchar(255)
);
insert into t_user(username) values('a');
insert into t_user(username) values('b');
insert into t_user(username) values('c');
insert into t_user(username) values('d');
insert into t_user(username) values('e');
insert into t_user(username) values('f');
id 字段设置为主键字段而且还自增,之后插入数据就不需要给 id 字段值了,会默认从 1 开始给你每行插入的数据的 id 字段给上一个值
/*不加括号和字段名也可以,只不过需要values部分顺序和数量跟表里的所有字段的顺序和数量一致才行*/
insert into t_student values(1,'zhangsan','1','gaosan1ban','1950-10-12');
/*如果数量不一致,就会报错!!! 错误:number of columns does not match*/
insert into t_student values(1,'zhangsan');/*错误的*/
create table dept1 as select * from dept; /*查询dept里的所有字段然后把这个查询结果当做表创建出来*/
insert into dept1 select * from dept; /*查询dept里的所有字段然后把这个查询结果当做数据插入dept1表里*/
select deptno, max(sal) as maxsal from emp group by deptno;/*找出每个部门最高薪水*/
/*用以上表当做临时表t,然后用来和emp e 表连接,连接条件为,deptno一样而且还sal等于maxsal*/
select e.ename from emp e join (select deptno, max(sal) as maxsal from emp group by deptno) t on e.deptno=t.deptno and e.sal = t.maxsal;