修改表
alter 修改表的结构
alter table table_name ADD column datatype AFTER column_1 在某一列后添加一列
alter table old_table_name rename to new_table_name 修改表名
alter table table_name character set 字符集 修改字符集
alter table table_name drop column 删除列
desc table_name 查看表结构
drop table table_name0 删除表
alter table table_name modify column datatype 修改列(列的属性,长度...
alter table table_name change column1 column2 datatype 将column1的列名改成column2
DML
insert、update、delete
insert 向表中插入数据
insert into table_name(列名) values(数据); 列名可以不写默认所有列添加数据
insert into table_name(列名) values(),(),()... 可以添加多条数据
1.插入数据类型与字段类型必须相同
2.插入数据长度应在列的规定范围内
3.列的排列位置和values中数据的排列一致
4.字符和日期数据包含在单引号中
5.列可以插入null空值,前提是字段允许为空
6.默认添加所有列的数据,列名可以不写
7.当不给某个字段值时,如果有默认值就会添加,否则报错
update更新表中数据
update table_name set 字段名=5000; 将所有该列所有记录改成5000
update table_name set 字段名=3000 where id=10; 将id为10的记录该字段改成3000
update table_name set 字段名=字段名+1000 where id=10; 将id为10的记录该字段改成原来的+1000
修改多个字段
update table_name set 字段1=值1,字段2=值2....
delete删除表中数据
delete 语句只能删除记录,不能删除一列,只可用update将一列置null
delete不删除表本身 删表用drop table_name
delete from table_name ; 删除表中所有数据
delete from table_name where id = 2,name='nanqi' 删除表中id字段=2且name字段=nanqi的数据
DQL
select单表查询
1.基本查询
select [DISTINCT] *| {column1,column2,column3..} from table_name;
distinct 去重,重复内容(所查询的每一条记录都相同,每一列相同)只显示一条
eg:
select * from table_name;查询表中所有记录
select id,name from table_name; 只显示id和name列的所有记录
对查询的列进行运算
select *| {column1 | expression,column2 | expression ..} from table_name;
给列取别名 select column_name as 别名 from table_name
eg:
select * name,(chinese+english+math) from student; 统计出每个学生的三门总分 ,显示学生和总分 (此时列名为(chinese+english+math)
用到别名
select * name,(chinese+english+math) AS total_score from student; //取别名为总分total_score
2.查询where子句使用运算符
比较运算符
1 > < <= >= = <> !=
2 between ...and... 显示某一区间的值(闭区间,包含两头)
3 IN(set) 显示在IN列表中的值 ,列:where in(100,200) 类似集合
4 模糊查询 like '张%' %匹配任意个字符,_匹配任意单个字符
not like ' '
5 is null 判断是否为空
逻辑运算符
1 and 多条件同时成立
2 or 多条件中任一成立
3 not 不成立 例:where not(salary > 100)
3.order by 子句查询
select *| column1,column2,column3 from table_name order by column asc|desc ...
asc(升序,默认) desc降序
order by语句应位于select语句的末尾
4.合计/统计函数
count :返回查询的结果有多少行
select count(*)|count(列名) from table_name where过滤
eg:
select count(*) from student; 统计student表中总共有多少行,不排除null
select count(列名) from student where 过滤条件 order by 排序规则; 统计满足条件的某列有多少条记录,但会排除该列为null的值
sum :返回满足where条件的行的和,一般用在数值列
select sum(列名) from table_name where 过滤条件
eg:
统计一个班所有人的数学总成绩
select sum(math) from sutdent;
统计一个班语文平均分
select sum(chinese) / count(*) as avg_score from student
avg :返回满足where条件的一列的平均值
eg:
统计一个班语文平均分
select avg(chinese) as avg_score from student
Max/Min :返回最大值,最小值
eg:
统计一个班语文最高分/最低分
select MAX(chinese) as avg_score from student
select MIN(chinese) as avg_score from student
5.group by子句分组
group by 和having 配合使用
group by子句对列进行分组
select column1,column2 ... from table_name group by column
eg:
select AVG(math),student,sex from class group by studnt,sex; 查询每个班级的男女生的数学平均分
having子句对group by 分组后的结果进行过滤
select column1,column2 ... from table_name group by column having ...
select name,avg(math) as math_avg,sex from student group by sex having math_avg >90; 显示男女生数学平均成绩大于90分的一方
6.字符串函数
select charset(math) from student; 返回该列的字符集 CHARSET
select concat(name,'math grade is',math) from student; 返回一列,合并列 CONCAT
select INSTR(String,subString) from DUAL 返回该subString在该字符串中的位置 INSTR DUAL :亚元表。可以当做测试表使用
UCASE 列名转为大写
LCASE 列名转为小写
LEFT(String,lenth) 从String的左边开始取length个字符
RIGHT(String,lenth) 从String的右边开始取length个字符
LENGTH 返回长度
replace(列(String),'原来的列名','替换后列名')
STRCMP(String1,String2) 逐字比较字符串大小
SUBSTRING(String,位置,length) String字符串从位置开始取到length个字符
lower(str)、upper(str)将字符串转为小、大写
7.数学函数
ABS(num) 取绝对值
BIN(num) 将数字转成二进制显示
ceiling(num) 比num大的最小整数 例:ceiling(1.1) -> 2
conv(num1,原来的进制,转成的进制) eg:conv(8,10,2) 将8从10进制转为2进制显示
FLOOR(num) 得到比num小的最大整数
format(num,decimal_places) 保留小数位数 (四舍五入保留) format(78.136985,2) 保留2位 78.14
LEAST 求最小值(num1,num2...) 多列数字结果比较
rand() 返回随机数 在[0,1]
rand([seed]) rand(3) 第一次产生随机数后就固定了
ceil向上取整、floor向下取整
MOD(X,Y)返回x/y的模
8.日期函数
current_date() 当前日期
current_time() 当前时间
current_timestamp() 当前时间戳
CURDATE();当前时间
NOW();返回当前日期和时间
DAY(DATE);获取指定date的“日”
MONTH(DATE);月 YEAR(DATE)年
DATEDIFF(date1,date2);date1和date2之间的天数
9.加密函数
USER()
DATABASE()
MD5(string)
PASSWORD(str)
10.流程控制函数
IF(expr1,expr2,expr3) 如果expr1为真,返回expr2,否则返回expr3
IFNULL(expr1,expr2) 如果expr1不为空,返回expr1,否则返回expr2
CASE WHEN expr1 THEN expr2 WHEN expr3 THEN expr4 ELSE expr5 END 如果expr1为真,返回expr2,如果expr1不为真,开始判断expr3是否为真,为真返回expr4,否则返回expr5 类似于多分支(if{} .. else if {} .. else{})
select单表增强查询
where子句 查找1992.1.1后入职的员工 emp表
mysql中日期类型可以直接比较
select * from where date > '1992-01-01';
like模糊查询
%:0-多个任意字符;
_ :表示单个任意字符
分页查询
select ... limit start,rows
表示从start+1行开始取,取出row行,start从0开始计算
start就是之前有多少行
分组增强
group by...
多子句查询顺序
select column1,,column2... from table_name group by column having condition order by column limit start,row;
group by :分组 having :group by后的过滤条件 order by :排序 limit :分页显示
多表关系
一对多(多对一)
在"多"的一方建立foreign key外键 references"一"的一方(主键列)
eg:员工与部门,两表均有id(emp,dept表),一个部门有多个员工,在emp表中添加外键(dept_id) ,保证数据正确,有效,完整
多对多(N-N)
多对多时,eg:一个学生可以选择多门课程,一个课程也可被多个学生选择
建立一张中间表维护两张表之间的关系,该表中至少要包含两个外键列(即两方的主键);
一对一
一对一的表关系通常用来做单表拆分,将有基本信息和详细信息的表拆分成两张表,以提高操作效率
实现方式:将任意一方中添加外键关联另一张表的主键,并且设置外键为唯一的(因为拆表后每条信息仍是唯一的,限定是一对一关系)
多表查询
多表查询是指基于两个和两个以上的表查询
笛卡尔积(查询所有可能结果)
当多表查询时筛选条件少于(表数量-1)时,会造成笛卡尔积
笛卡尔积(多表默认查询):两个表记录组合(将第一张表的记录取出一行和第二张表的所有行进行组合),将多表的所有列都查询出来,
所有多表查询重点在于过滤条件
select empNO,deptNo from emp,dept where sal between los and his(过滤条件);
自连接
自连接是在同一张表的连接查询[将同一张表看做两张表使用]
select worker.ename as '职工',boss.ename as '上级' from emp worker,emp boss where worker.mgr = boss.empno;
将emp取两个别名(不用写as): emp worker,emp boss ----->表名 表别名
子查询
子查询是指嵌入在其它sql语句的select语句,也叫嵌套语句
单行子查询(标量子查询)
返回一行数据的子查询语句
eg:查询和SMITH相同部门的所有员工信息
select * from emp where deptno = (select deptno from emp where ename = 'SMITH') ;通过子查询查到SMITH所属部门号
多行子查询
返回多行数据的子查询语句 使用关键字 IN
eg:查询和部门号为10的工作相同的员工的名称,工作,薪水,部门编号(除去10号部门的信息)
select ename,job,sal,deptno from emp where job in (select distinct job from emp where deptno = 10) and deptno <> 10;
<> != 都可以表示不等于 IN用于子查询结果为多行
子查询当做临时表使用
查新ecs_goods中各个类别,价格最高的商品
select goods_id,ecs_goods.cat_id,goods_name,shop_price from (select cat_id,max(shop_price) as max_price from ecs_goods group by cat_id) temp,esc_goods where temp.cat_id = ecs_goods.cat_id and temp.max_price = ecs_goods.shop_price
select 后只能 跟 group by 分组的字段(即字段相同)
在多行子查询中 all和any
all
eg:查询工资比 部门30的所有员工工资都高 的员工的姓名、工资和部门号
select ename,sal,deptno from emp where sal>all(select sal from emp where deptno = 30); sal>子查询所有的sal
也可写成select ename,sal,deptno from emp where sal> (select max(sal) from emp where deptno = 30);
any
eg:查询工资比 部门30的其中一个员工工资高就行 的员工的姓名、工资和部门号(不包括30号部门)
select ename,sal,deptno from emp where sal>any(select sal from emp where deptno = 30) and deptno <> 30;
也可写成select ename,sal,deptno from emp where sal> (select min(sal) from emp where deptno = 30) and deptno <> 30;
多列子查询
where (column1,column2) = (select column1,column2 .........)
返回多列数据的子查询
查出和smith相同部门和岗位的所有员工信息(除了smith)
select * from emp where (deptno,job) = (select deptno,job from emp where ename = 'smith') and ename <> 'smith';
子查询Exercise
查找每个部门工资高于本部门工资的人的资料
select * from (select avg(sal) as avg_sal,deptno from emp group by deptno)tmp,emp where emp.sal > tmp.avg_sal and emp.deptno = tmp.deptno;
查找每个部门工资最高的人的资料
select * from (select max(sal) as max_sal,deptno from emp group by deptno)tmp,emp where emp.sal = tmp.max_sal and emp.deptno = tmp.deptno;
查询每个部门的信息(包括部门编号、部门名、地址)和人员数量
select dept.deptno,dname,loc,count from dept left join (select deptno,count(ename) as count from emp group by deptno)tmp on tmp.deptno = dept.deptno; (用left join 为了40部门没有人也要显示)
表复制和去重
自我复制数据(蠕虫复制)
为了对某个sql语句进行效率测试,需要海量测试时,可用此法为表创建海量数据
先新创一张表
mysql> create table if not exists my_tab01(
-> id int, -> `name` varchar(32), -> sal double, -> job varchar(32), -> deptno int); 将emp中的数据添加到my_tab01中 insert into my_tab01(id,`name`,sal,job,deptno) select empno,ename,sal,job,deptno from emp;
自我复制insert into my_tab01 select * from my_tab01;
去重
如何去掉一张表中的重复记录?
先创建一张表
create my_tab02 like emp; //创建一张表结构跟emp表一致
insert into my_tab02 select * from emp; //插入emp表数据,执行2次,有重复数据
开始去重
1.先创建一张临时表,该表结构和my_tab02一致
create table my_tab02 like emp
2.把my_tab02表的数据distinct去重后复制到my_tmp
insert into my_tmp select distinct * from my_tab02
3.清空my_tab02表中的数据
delete from my_tab02;
4.把my_tmp表中数据复制到my_tab02
insert into my_tab02 select * from my_tmp;
5.drop删除表my_tmp;
drop table my_tmp;
在第二步之后也可以删除表my_tab02,将my_tmp改为my_tab02(alter table my_tmp rename to my_tab02);
union,union all合并查询
该操作符用于取得两个结果集的并集。
该查询到的两个结果必须列数一致,字段类型也一致
union
合并去重
两条查询出来的结果进行合并
select ename,sal,job from emp where sal > 2500 union select ename,sal,job from emp where job = 'MANAGER';
union all
会自动去重相同的记录
select ename,sal,job from emp where sal > 2500 union all select ename,sal,job from emp where job = 'MANAGER';