create table t1(
id int,
name varchar(32),
age int,
gneder varchar(5)
);
create table 库名.表名(
字段名1 数据类型 约束条件 约束条件 约束条件 约束条件,
字段名2 数据类型 约束条件 约束条件 约束条件 约束条件,
字段名3 数据类型 约束条件 约束条件 约束条件 约束条件,
字段名4 数据类型 约束条件 约束条件 约束条件 约束条件,
字段名5 数据类型 约束条件 约束条件 约束条件 约束条件,
字段名6 数据类型 约束条件 约束条件 约束条件 约束条件
);
insert into 库名.t1 values('1', 2, 3, 4, 5, 6);
约束条件其实就是在数据类型的基础之上在做约束
create table t2(id int unsigned); 这是给字段去符号的
如果添加的数是带符号的就会报错
insert into t2 values(-1);
# ERROR 1264 (22003): Out of range value for column 'id' at row 1
create table t4 (id int(10) zerofill); 位数不够的时候用0填充,只能和int一起使用
'''
mysql> insert into t4 values(5);
Query OK, 1 row affected (0.01 sec)
mysql> select * from t4;
+------------+
| id |
+------------+
| 0000000005 |
+------------+
1 row in set (0.00 sec)
'''
mysql> create table t5(id int, name varchar(32) default'jack'); 更改了Default的默认值,不更改默认就是NULL
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(32) | YES | | jack | |
+-------+-------------+------+-----+---------+-------+
mysql> create table t6(id int, name varchar(32) not null);
在name后面添加了约束语非空后,name必须要填写数据否则就报错
mysql> desc t6;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(32) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
insert into t6 values(1);
# ERROR 1136 (21S01): Column count doesn't match value count at row 1
insert into t6 values(1,'jack');
select * from t6;
+------+------+
| id | name |
+------+------+
| 1 | jack |
+------+------+
1.单唯一
create table t7(id int, name varchar(32) unique);
添加了单唯一后name就不能再重复添加,否则报错
2.多唯一
create table t8 (id int,name varchar(32),unique(id, name));
以上两个都不能重复
主键单从约束条件上来看,它相当于是非空且唯一 unique not null
id unique not null ---------> id primary key
create table t8 (id int primary key);
create table t8 (id int unique not null);
InnoDB存储引擎规定每一张表都要有一个主键,但是,我之前创建的表都没有指定主键, 表是怎么创建成功的?
是因为InnoDB存储引擎内部有一个隐藏的主键,这个主键我们看不到,它也不能够加快查询速度,仅仅是为了帮助我们把表创建成功. 所以,以后我们创建表的时候都主动的创建一个主键,我们自己创建的主键能够加快查询速度,因为是一个索引.
一般情况下,主键应该创建哪个字段? 大多都给id字段加了,所以,每一张表都要有一个id字段,并且一张表中不只是有一个主键,可以有多个主键,但是,大多数情况下,都只有一个
create table t9(id int primary key, name varchar(32));
insert into t9 values(1,'jack'),(2,'jak1');
添加了主键后id不能相同且非空
一般情况下都配和主键使用
create table t11(id int primary key auto_increment, name varchar(32));
insert into t11(name) values('tank'),('jarry');
插入数据,在表名后面加上需要添加数据的那一个字段,如果有多个字段就需要添加多个。
+----+-------+
| id | name |
+----+-------+
| 1 | jack |
| 2 | jack |
| 3 | jack |
| 4 | kevin |
| 5 | tank |
| 6 | jarry |
+----+-------+
create table t123(id int(5)); 括号里的数字不代表范围
create table t123(id int(5) zerofill); 括号里的数字不代表范围
1. delete from t; # 不会重置id值
2. truncate t9; # 清空表、重置id值
3.
truncate:建议使用truncate,使用这个,万一你清空错了,还有机会恢复
mysql它有很多个日志文件,binlog日志-----》可以恢复数据,记录了你所有的SQL语句
语法:
1. 修改表名
ALTER TABLE 表名
RENAME 新表名;
2. 增加字段
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…],
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…] FIRST;
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…] AFTER 字段名;
3. 删除字段
ALTER TABLE 表名
DROP 字段名;
4. 修改字段 # modify只能改字段数据类型完整约束,不能改字段名,但是change可以!
ALTER TABLE 表名
MODIFY 字段名 数据类型 [完整性约束条件…];
ALTER TABLE 表名
CHANGE 旧字段名 新字段名 旧数据类型 [完整性约束条件…];
"""除了以上的SQL语句,还有很多其他的,如果遇到了不会写,就直接搜索引擎"""
# 数据准备
create table emp(
id int primary key auto_increment,
name varchar(20) not null,
sex enum('male','female') not null default 'male', #大部分是男的
age smallint(3) unsigned not null default 28,
hire_date date not null,
post varchar(50),
post_comment varchar(100),
salary double(15,2),
office int, #一个部门一个屋子
depart_id int
);
insert into emp(name,sex,age,hire_date,post,salary,office,depart_id) values
('tom','male',78,'20150302','teacher',1000000.31,401,1),#以下是教学部
('kevin','male',81,'20130305','teacher',8300,401,1),
('tony','male',73,'20140701','teacher',3500,401,1),
('owen','male',28,'20121101','teacher',2100,401,1),
('jack','female',18,'20110211','teacher',9000,401,1),
('jenny','male',18,'19000301','teacher',30000,401,1),
('sank','male',48,'20101111','teacher',10000,401,1),
('哈哈','female',48,'20150311','sale',3000.13,402,2),#以下是销售部门
('呵呵','female',38,'20101101','sale',2000.35,402,2),
('西西','female',18,'20110312','sale',1000.37,402,2),
('乐乐','female',18,'20160513','sale',3000.29,402,2),
('拉拉','female',28,'20170127','sale',4000.33,402,2),
('僧龙','male',28,'20160311','operation',10000.13,403,3), #以下是运营部门
('程咬金','male',18,'19970312','operation',20000,403,3),
('程咬银','female',18,'20130311','operation',19000,403,3),
('程咬铜','male',18,'20150411','operation',18000,403,3),
('程咬铁','female',18,'20140512','operation',17000,403,3);
创建完之后得到这样的一张表
where是筛选的条件
"""
模糊查询:没有明确的筛选条件
关键字:like
关键符号:
%:匹配任意个数任意字符
_:匹配单个个数任意字符
show variables like '%mode%';
"""
like筛选功能
"""
模糊查询:没有明确的筛选条件
关键字:like
关键符号:
%:匹配任意个数任意字符
_:匹配单个个数任意字符
show variables like '%mode%se';
"""
mysql> select * from emp where id >=3 and id <= 6;
+----+-------+--------+-----+------------+---------+--------------+----------+--------+-----------+
| id | name | sex | age | hire_date | post | post_comment | salary | office | depart_id |
+----+-------+--------+-----+------------+---------+--------------+----------+--------+-----------+
| 3 | tony | male | 73 | 2014-07-01 | teacher | NULL | 3500.00 | 401 | 1 |
| 4 | owen | male | 28 | 2012-11-01 | teacher | NULL | 2100.00 | 401 | 1 |
| 5 | jack | female | 18 | 2011-02-11 | teacher | NULL | 9000.00 | 401 | 1 |
| 6 | jenny | male | 18 | 1900-03-01 | teacher | NULL | 30000.00 | 401 | 1 |
+----+-------+--------+-----+------------+---------+--------------+----------+--------+-----------+
select * from emp where salary=20000 or salary=18000 or salary=17000;
select * from emp where salary in (20000,18000,17000); # 简写
+----+-----------+--------+-----+------------+-----------+--------------+----------+--------+-----------+
| id | name | sex | age | hire_date | post | post_comment | salary | office | depart_id |
+----+-----------+--------+-----+------------+-----------+--------------+----------+--------+-----------+
| 14 | 程咬金 | male | 18 | 1997-03-12 | operation | NULL | 20000.00 | 403 | 3 |
| 16 | 程咬铜 | male | 18 | 2015-04-11 | operation | NULL | 18000.00 | 403 | 3 |
| 17 | 程咬铁 | female | 18 | 2014-05-12 | operation | NULL | 17000.00 | 403 | 3 |
+----+-----------+--------+-----+------------+-----------+--------------+----------+--------+-----------+
在你刚开始接触mysql查询的时候,建议你按照查询的优先级顺序拼写出你的sql语句
"""
先是查哪张表 from emp
再是根据什么条件去查 where name like ‘%o%’
再是对查询出来的数据筛选展示部分 select name,salary
"""
mysql> select name,salary from emp where name like '%o%';
+------+------------+
| name | salary |
+------+------------+
| tom | 1000000.31 |
| tony | 3500.00 |
| owen | 2100.00 |
+------+------------+
mysql> select name,salary from emp where name like '____';
+------+----------+
| name | salary |
+------+----------+
| tony | 3500.00 |
| owen | 2100.00 |
| jack | 9000.00 |
| sank | 10000.00 |
+------+----------+
4 rows in set (0.00 sec)
mysql> select name,salary from emp where char_length(name) = 4;
+------+----------+
| name | salary |
+------+----------+
| tony | 3500.00 |
| owen | 2100.00 |
| jack | 9000.00 |
| sank | 10000.00 |
+------+----------+
select * from emp where id not between 3 and 6;
+----+-----------+--------+-----+------------+-----------+--------------+------------+--------+-----------+
| id | name | sex | age | hire_date | post | post_comment | salary | office | depart_id |
+----+-----------+--------+-----+------------+-----------+--------------+------------+--------+-----------+
| 1 | tom | male | 78 | 2015-03-02 | teacher | NULL | 1000000.31 | 401 | 1 |
| 2 | kevin | male | 81 | 2013-03-05 | teacher | NULL | 8300.00 | 401 | 1 |
| 7 | sank | male | 48 | 2010-11-11 | teacher | NULL | 10000.00 | 401 | 1 |
| 8 | 哈哈 | female | 48 | 2015-03-11 | sale | NULL | 3000.13 | 402 | 2 |
| 9 | 呵呵 | female | 38 | 2010-11-01 | sale | NULL | 2000.35 | 402 | 2 |
| 10 | 西西 | female | 18 | 2011-03-12 | sale | NULL | 1000.37 | 402 | 2 |
| 11 | 乐乐 | female | 18 | 2016-05-13 | sale | NULL | 3000.29 | 402 | 2 |
| 12 | 拉拉 | female | 28 | 2017-01-27 | sale | NULL | 4000.33 | 402 | 2 |
| 13 | 僧龙 | male | 28 | 2016-03-11 | operation | NULL | 10000.13 | 403 | 3 |
| 14 | 程咬金 | male | 18 | 1997-03-12 | operation | NULL | 20000.00 | 403 | 3 |
| 15 | 程咬银 | female | 18 | 2013-03-11 | operation | NULL | 19000.00 | 403 | 3 |
| 16 | 程咬铜 | male | 18 | 2015-04-11 | operation | NULL | 18000.00 | 403 | 3 |
| 17 | 程咬铁 | female | 18 | 2014-05-12 | operation | NULL | 17000.00 | 403 | 3 |
+----+-----------+--------+-----+------------+-----------+--------------+------------+--------+-----------+
select name,post from emp where post_comment is null;
+-----------+-----------+
| name | post |
+-----------+-----------+
| tom | teacher |
| kevin | teacher |
| tony | teacher |
| owen | teacher |
| jack | teacher |
| jenny | teacher |
| sank | teacher |
| 哈哈 | sale |
| 呵呵 | sale |
| 西西 | sale |
| 乐乐 | sale |
| 拉拉 | sale |
| 僧龙 | operation |
| 程咬金 | operation |
| 程咬银 | operation |
| 程咬铜 | operation |
| 程咬铁 | operation |
+-----------+-----------+
分组:按照某个指定的条件将单个单个的个体分成一个个的整体
比如:按照男女分组,按照年龄分组
单纯的分组时没有意义的
在MySQL中分组之后,只能够获得分组的依据! 按照哪个字段分组就只能获取这个字段的值,别的字段不能拿到
分组一般配合聚合函数使用:
sum max min avg count
分组的关键字:group by
# 数据分组应用场景:每个部门的平均薪资,男女比例等
# 1.按部门分组
1. 分组之后默认可以获取所有的字段信息
2. 分组之后,展示的数据都是每个组的第一条数据
分组之后默认只能够直接过去到分组的依据 其他数据都不能直接获取
针对5.6需要自己设置sql_mode
set global sql_mode = ‘only_full_group_by,STRICT_TRANS_TABLES,PAD_CHAR_TO_FULL_LENGTH’;
聚合函数主要就是配合分组一起使用
max min sum count avg
select * from emp group by post; # 分组后取出的是每个组的第一条数据
select id,name,sex from emp group by post; # 验证
"""
设置sql_mode为only_full_group_by,意味着以后但凡分组,只能取到分组的依据,
不应该在去取组里面的单个元素的值,那样的话分组就没有意义了,因为不分组就是对单个元素信息的随意获取
"""
set global sql_mode="strict_trans_tables,only_full_group_by";
#重新链接客户端
select * from emp group by post; # 报错
select id,name,sex from emp group by post; # 报错
select post from emp group by post; # 获取部门信息
#强调:只要分组了,就不能够再“直接”查找到单个数据信息了,只能获取到组名
# 以组为单位统计组内数据>>>聚合查询(聚集到一起合成为一个结果)
# 每个部门的最高工资
select post,max(salary) from emp group by post;
补充:在显示的时候还可以给字段取别名
select post as '部门',max(salary) as '最高工资' from emp group by post;
as也可以省略 但是不推荐省 因为寓意不明确
# 每个部门的最低工资
select post,min(salary) from emp group by post;
# 每个部门的平均工资
select post,avg(salary) from emp group by post;
# 每个部门的工资总和
select post,sum(salary) from emp group by post;
# 每个部门的人数
select post,count(id) from emp group by post;
统计的时候只要是非空字段 效果都是一致的
这里显示age,salary,id最后演示特殊情况post_comment
# group_concat 分组之后使用
如果真的需要获取分组以外的数据字段 可以使用group_concat()
# 每个部门的员工姓名
select post,group_concat(name) from emp group by post;
select post,group_concat(name,'|',sex) from emp group by post;
select post,group_concat(name,'|',sex, '|', gender) from emp group by post;
select post,group_concat(distinct name) from emp group by post;
select post,group_concat(distinct name separator '%') from emp group by post;
# concat 不分组使用
select concat(name,sex) from emp;
select concat(name,'|',sex) from emp;
# concat_ws()
select post,concat_ws('|', name, age, gender) from emp group by post;
where与having都是筛选功能 但是有区别
where在分组之前对数据进行筛选
having在分组之后对数据进行筛选
1.统计各部门年龄在30岁以上的员工平均薪资,并且保留平均薪资大于10000的部门.
# 先筛选出年龄在30岁以上的
select * from emp where age > 30;
# 在进行分组,按照部门分组
select avg(salary) as avg_salary from emp where age > 30 group by post;
# 保留平均薪资大于10000的部门
select avg(salary) as avg_salary from emp where age > 30 group by post having avg(salary) > 10000;
distinct:去重
"""带主键的数据去重有没有意义? 没有,主键本身就是唯一的"""
select distinct id,age from emp;
select * from emp order by salary; #默认升序排
select * from emp order by salary desc; #降序排
#先按照age降序排,在年轻相同的情况下再按照薪资升序排
select * from emp order by age desc,salary;
'''多字段排序,如果想让后面的字段排序生效,前提:前面的排序字段必须一样'''
# 统计各部门年龄在20岁以上的员工平均工资,并且保留平均工资大于1000的部门,然后对平均工资进行排序
# 20岁以上的员工
select * from emp where age > 20;
# 各部门的平均薪资
select avg(salary) from emp where age > 20 group by post having avg(salary) > 1000;
#
select avg(salary) from emp where age > 20 group by post having avg(salary) > 1000 order by avg(salary) desc;
# 限制展示条数
# 限制展示条数
select * from emp limit 3;
# 查询工资最高的人的详细信息
select * from emp order by salary desc limit 1;
# 分页显示
select * from emp limit 0,5; # 第一个参数表示起始位置,第二个参数表示的是条数,不是索引位置
select * from emp limit 5,5;
select * from emp where name regexp '^j.*(n|y)$';