MySQL数据库基本SQL语句练习

mysql> create database test; –创建一个叫test的库
mysql> create database test character set=utf8; –创建库的时候,指定非默认的字符集
mysql> alter database test character set=gbk; –修改一个库的字符集
mysql> drop database test; –删除test库
mysql> use test; –使用test库
mysql> create table emp (ename varchar(20),sex char(1),hiredate date,sal decimal(10,2),deptno tinyint(1)); –创建表
mysql> show create table emp; –查看创建表的参数,引擎和默认的字符集
mysql> alter table emp engine=memory; –修改表的引擎
mysql> alter table emp default charset=utf8; –修改表的字符集
mysql> drop table emp; –删除emp表
mysql> create table emp ( ename varchar(20), sex char(1), hiredate date, sal decimal(10,2), deptno tinyint(1)) engine=memory default charset=utf8; –也可以在创建表时直接指定非默认的引擎或字符集
mysql> create table dept (deptno tinyint(1),deptname varchar(30),location varchar(50)); –再创建一个部门表,注意deptno这一列和emp表的deptno列是对应的
–选择字符集的原则
1,如果应用要处理各种各样的文字,或者要发布到使用不同语言的国家或地区,就应该选择unicode字符集。对mysql来说,目前就是UTF-8
2,如果应用涉及已有数据的导入,就要充分考虑数据库字符集对已有数据的兼容性;假如已有数据是GBK,选择GB2312-80为数据库字符集,就很可能出现某些文字无法正确导入的问题
3,如果数据库只需要支持一般中文,数据量很大,性能要求也很高,那就应该选择双字节定长编码的中文字符集,如GBK。相对于UTF-8来说,GBK比较小,只占2个字节,相对于UTF-8汉字编码要3个字节来说,可以减少I/O,数据库cache以及网络传输时间,提高性能。
如果主要处理英文字符,仅有少量汉字数据,则选择UTF-8更好,因为GBK的西文字符编码都为2个字节,会造成很大不必要的开销。
4,如果数据库需要做大量的字符运算,如比较,排序等,选择定长字符集可能更好,因为定长字符集的处理速度要比变长字符集的处理速度快。
5,如果所有客户端程序都支持相同的字符集,应该优先选择此字符集作为数据库字符集,这样可以避免因字符集转换带来的性能开销和数据损失。
mysql可以支持多种字符集,在同一台服务器,同一个数据库甚至同一个表的不同字段都可以指定使用不同的字符集,相比oracle等其他数据库在同一个数据库上只能使用相同的字符集,mysql明显存在更大的灵活性。
mysql> show character set; –查看所有可用的字符集
mysql> alter table emp add column age tinyint(1); –增加一个列,默认增加到最后

mysql> alter table emp add column manager varchar(30) after hiredate; –在hiredate这列后面增加一列,使用after关键字

mysql> alter table emp add column manageraaaa varchar(30) first; –把一列加到最前面,使用first关键字
–first和after是mysql自己的SQL语法扩展,在oracle数据库里就没有这种功能,它需要使用select按需求的顺序给选取出来,再导入到新表,删除老表
–比如说加了一个age列,要把age列放到最前面,则需要select时把age列放在第一位,再创建成emp1表
mysql> create table emp1 as select age,ename,sex,hiredate,sal,deptno from emp ;
mysql> drop table emp; –删除emp表
mysql> rename table emp1 to emp; –再把emp1表重命名成emp

mysql> alter table emp modify manager varchar(40); –使用modify修改一列的数据类型

mysql> alter table emp change manager manager varchar(30); –使用change修改一列的数据类型

mysql> alter table emp change manager mana varchar(30); –修改列名要使用change去修改

–modify和change的区别,都可以修改数据类型,但change要写原列名;只有change可以修改列名,modify不可以

mysql> alter table emp drop manageraaaa; –删除某一列
练习:通过上面的命令,把emp表多加三列,成为下面的格式
+———–+—————+——+—–+———+——-+
| Field | Type | Null | Key | Default | Extra |
+———–+—————+——+—–+———+——-+
| empno | int(11) | YES | | NULL | |
| ename | varchar(20) | YES | | NULL | |
| sex | char(1) | YES | | NULL | |
| birthday | date | YES | | NULL | |
| hiredate | date | YES | | NULL | |
| sal | decimal(10,2) | YES | | NULL | |
| deptno | tinyint(1) | YES | | NULL | |
| managerno | int(11) | YES | | NULL | |
+———–+—————+——+—–+———+——-+
mysql> alter table emp add empno int first;

mysql> alter table emp add birthday date after sex;

mysql> alter table emp add managerno int;

mysql> truncate table emp; –截断表,清空了表内的所有数据,但是表的结构还在

例:简述 drop,delete,truncate的区别?

drop 可以删库,表等整个对象;delete和truncate只能删表里的数据

drop和truncate属于DDL,在事务控制里是不用commit提交的;delete属于DML,需要commit提交;

高水位线(high watermark)
比如100W行的一张表,用delete或truncate删完数据。delete水位线不下降,truncate下降。

mysql> insert into aaa.emp values (1,’boss’,’m’,’1964-08-08’,’1995-01-01’,’20000’,’1’,’1’)
–插入数据,注意在mysql里数字可以不用加引号,别的都加引号

mysql> insert into emp values
-> (1,’boss’,’m’,’1964-08-08’,’1995-01-01’,’20000’,’1’,’1’),
->(2,’zhangsan’,’m’,’1967-04-05’,’1995-04-11’,’15000’,’2’,’1’);
Query OK, 2 rows affected, 0 warning (0.02 sec)
Records: 2 Duplicates: 0 Warnings: 0
–一次插入多条记录

还可以插入特定的列(非所有列),那么没有插入的就成了空值(空值不是0,它做任何运算结果还是空值)

mysql> insert into emp (ename,sex) values (‘lisi’,’m’);
下面针对上面的新表结构,直接插入9列数据
insert into test.emp values (1,’boss’,’m’,’1964-08-08’,’1995-01-01’,’20000’,’1’,’1’),(2,’zhangsan’,’m’,’1967-04-05’,’1995-04-11’,’15000’,’2’,’1’),(3,’lisi’,’f’,’1973-01-28’,’1998-11-21’,’13000’,’3’,’1’),(4,’wangwu’,’f’,’1975-06-03’,’1999-12-12’,’12000’,’4’,’1’),(5,’maliu’,’m’,’1982-08-18’,’2001-07-03’,’8000’,’2’,’2’),(6,’tianqi’,’f’,’1983-02-15’,’2002-11-01’,’7000’,’2’,’2’),(7,’mark’,’m’,’1984-08-12’,’2003-10-02’,’6500’,’3’,’3’),(8,’john’,’m’,’1985-09-14’,’2005-04-03’,’6000’,’3’,’3’),(9,’mm’,’f’,’1990-06-08’,’2008-09-13’,’4000’,’4’,’4’);
mysql> select * from test.emp;
+——-+———-+——+————+————+———-+——–+———–+
| empno | ename | sex | birthday | hiredate | sal | deptno | managerno |
+——-+———-+——+————+————+———-+——–+———–+
| 1 | boss | m | 1964-08-08 | 1995-01-01 | 20000.00 | 1 | 1 |
| 2 | zhangsan | m | 1967-04-05 | 1995-04-11 | 15000.00 | 2 | 1 |
| 3 | lisi | f | 1973-01-28 | 1998-11-21 | 13000.00 | 3 | 1 |
| 4 | wangwu | f | 1975-06-03 | 1999-12-12 | 12000.00 | 4 | 1 |
| 5 | maliu | m | 1982-08-18 | 2001-07-03 | 8000.00 | 2 | 2 |
| 6 | tianqi | f | 1983-02-15 | 2002-11-01 | 7000.00 | 2 | 2 |
| 7 | mark | m | 1984-08-12 | 2003-10-02 | 6500.00 | 3 | 3 |
| 8 | john | m | 1985-09-14 | 2005-04-03 | 6000.00 | 3 | 3 |
| 9 | mm | f | 1990-06-08 | 2008-09-13 | 4000.00 | 4 | 4 |
+——-+———-+——+————+————+———-+——–+———–+
9 rows in set (0.00 sec)
把dept表也插入记录,方便下面的实验
mysql> insert into dept values
-> (1,’manager’,’beijing’),
-> (2,’it’,’shenzhen’),
-> (3,’sale’,’shanghai’),
-> (4,’services’,’guangzhou’);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0

mysql> select * from dept;
+——–+———-+———–+
| deptno | deptname | location |
+——–+———-+———–+
| 1 | manager | beijing |
| 2 | it | shenzhen |
| 3 | sale | shanghai |
| 4 | services | guangzhou |
+——–+———-+———–+
4 rows in set (0.00 sec)

===============================================================
update

把wangwu性别改成m

mysql> update emp set sex=’m’ where ename=’wangwu’;

wangwu的工资加500

mysql> update emp set sal=sal+500 where ename=’wangwu’;

2号部门的工资涨10%

mysql> update emp set sal=sal+sal*0.1 where deptno=2;

mark由3号部门换成2号部门,同时工资加1000,上级管理者也改为2号部门的头

mysql> update emp set deptno=’2’ and sal=sal+1000 and managerno=2 where ename=’mark’; –错误写法

mysql> update emp set deptno=’2’,sal=sal+1000,managerno=2 where ename=’mark’; –正确写法
工资就john和mark涨10%,其它人不涨
mysql> update emp set sal=sal+sal*0.1 where ename=’john’ or ename=’mark’;

mysql> update emp set sal=sal+sal*0.1 where ename in (‘john’,’mark’);

工资都涨10%,john和mark犯错误,就他们不涨
mysql> update emp set sal=sal+sal*0.1 where ename!=’john’ and ename<>’mark’;

mysql> update emp set sal=sal+sal*0.1 where ename not in (‘john’,’mark’);

delete

delete from emp where xxxx;


DQL

select

mysql> select * from emp; –* 代表查看所有列

mysql> select ename,sal from emp; – 只查看其中几列

mysql> select distinct deptno from emp; –distinct 去除重复行
查询所有男员工的姓名和工资
mysql> select ename,sal from emp where sex=’m’;

查询所有工资大于8000的员工的所有信息
mysql> select * from emp where sal>8000;

查询所有工资在4000到8000之间的员工的所有信息(包含4000和8000的)

mysql> select * from emp where sal>=4000 and sal<=8000;
mysql> select * from emp where sal between 4000 and 8000;

查询入职时间在2001那年的员工的姓名和工资
mysql> select ename,sal from emp where year(hiredate)=2001;
mysql> select ename,sal from emp where substr(hiredate,1,4)=2001;
mysql> select ename,sal from emp where hiredate>’2000-12-31’ and hiredate<’2002-01-01’;
mysql> select ename,sal from emp where hiredate >= ‘2001-01-01’ and hiredate <= ‘2001-12-31’;
mysql> select ename,sal from emp where hiredate like ‘2001%’;

查询2002年之后(包括2002年)入职的,并且工资大于8000的员工姓名

mysql> select ename from emp where year(hiredate)>=2002 and sal>8000;

--------------------------
排序操作统计工资总额,最大工资,最小工资,平均工资
mysql> select * from emp order by sal; –以工资排序,默认升序排序
mysql> select * from emp order by sal asc; –加不加asc都是升序

mysql> select * from emp order by sal desc; –desc表示降序排序

mysql> select * from emp order by sex,sal;
–先按性别排,再按工资排。结果是女的都在一起,以工资从小到大排。男的都在一起,以工资从小到大排。
mysql> select * from emp order by sex desc,sal desc;

找出工资最低的三个人的姓名和工资
mysql> select ename,sal from emp order by sal limit 3;

找出工资最高的三个人的姓名和工资

mysql> select ename,sal from emp order by sal desc limit 3;

找出工资最低的女员工的姓名和工资

mysql> select ename,sal from emp where sex=’f’ order by sal limit 1;

找出工资从高到低第三到第五的人的姓名和工资

mysql> select * from emp order by sal desc limit 2,3;

聚合和分组操作:

mysql> select count(*) from emp; –统计记录条数

mysql> select count(distinct deptno) from emp;
+————————+
| count(distinct deptno) |
+————————+
| 4 |
+————————+
1 row in set (0.00 sec)

mysql> select count(distinct deptno) deptcount from emp; –别名
+———–+
| deptcount |
+———–+
| 4 |
+———–+

统计每个部门的人数
mysql> select deptno,count(*) from emp group by deptno;

mysql> select ename,deptno,count(*) from emp group by deptno;
–这种在mysql里可以查,但无意义,在oracle里属于错误语法。因为前面select的列名除了count(),max(),min(),avg(),sum()等外,别的列名都必须在group by里

统计男,女员工各有多少人
mysql> select sex,count(*) from emp group by sex;

统计每个部门里男女员工各有多少个

mysql> select deptno,sex,count(*) from emp group by deptno,sex;

查找部门人数大于2的部门号和人数

mysql> select deptno,count() from emp group by deptno having count()>2;
求每个部门的工资总额,最大工资,最小工资,平均工资
mysql> select deptno,sum(sal),max(sal),min(sal),avg(sal) from emp group by deptno;

统计工资总额,最大工资,最小工资,平均工资

mysql> select sum(sal),max(sal),min(sal),avg(sal) from emp;

表链接(多表查询)
查出员工姓名和其对应的工资,部门名,部门所在地,并显示

mysql> select ename,sal,deptname,location from emp,dept where emp.deptno=dept.deptno;

mysql> select ename,sal,deptname,location from emp e,dept d where e.deptno=d.deptno;

------------------------

子查询:
查出比wangwu工资高的人的姓名和工资

mysql> select ename,sal from emp where sal>(select sal from emp where ename=’wangwu’);


DCL

grant 授权

mysql> grant select,insert on aaa.emp to ‘aa’@’localhost’ identified by ‘123’; –授权使aa@localhost用户,对aaa库的emp表拥有select和insert权限
mysql> flush privileges; –刷新权限

mysql> revoke select on aaa.emp from ‘aa’@’localhost’; –回收aa@localhost用户对aaa库的emp的select权限
mysql> flush privileges;

远程授权

服务端
mysql> grant all on . to ‘aa’@’%’ identified by ‘123’; –all代表所有权限,.代表所有库的所有表 %代表所有IP
mysql> flush privileges;

客户端

[root@li ~]# /usr/local/mysql/bin/mysql -u aa -h 10.1.1.35 -p123 -P 3307

-p 参数表示密码,-P参数表示端口 ,如果是使用默认的3306就不用改端口