创建表的完整语法
约束条件(在数据类型的基础上在进行约束)
unsigned
zerofill
default
not null
unique
primary key
auto_increment
补充一些别的SQL语句
其他查询关键字
select
from
where
order by
limit
having
regexp
and or in not in between and like 等
create table t1(id int, name varchar(43), age int);
create table 库名.表名(字段名 数据类型 约束条件,字段名1 数据类型 约束条件);
insert into 库民.表名 values(1,2);
1.字段名和数据类型是必须写的,不能忽略
2.约束条件是可选的,可有可无,而且有多个
3.表结构中最一个字段不能有逗号
mysql> create table t1(id int unsigned);
Query OK, 0 rows affected (0.04 sec)
mysql> insert into t1 values(-10);
ERROR 1264 (22003): Out of range value for column 'id' at row 1
mysql> insert into t1 values(10);
Query OK, 1 row affected (0.01 sec)
mysql> select * from t1;
+------+
| id |
+------+
| 10 |
+------+
1 row in set (0.00 sec)
mysql>
mysql> create table t2(id int(5) zerofill);
Query OK, 0 rows affected (0.04 sec)
mysql> insert into t2 values(123);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t2;
+-------+
| id |
+-------+
| 00123 |
+-------+
1 row in set (0.00 sec)
mysql>
mysql> create table t3(id int,name varchar(32) default 'wzc');
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t3(id) values(1);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t3;
+------+------+
| id | name |
+------+------+
| 1 | wzc |
+------+------+
1 row in set (0.00 sec)
mysql> create table t4(id int,name varchar(32) not null);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t4(id) values(1);
ERROR 1364 (HY000): Field 'name' doesn't have a default value
mysql> select * from t4;
Empty set (0.00 sec)
mysql> create table t5(id int,name varchar(32) unique);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t5 values(1,'wzc');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t5 values(2,'wzc');
ERROR 1062 (23000): Duplicate entry 'wzc' for key 'name'
多列唯一
mysql> create table t6(id int, ip varchar(32),port varchar(32),unique(ip,port));
Query OK, 0 rows affected (0.03 sec)
mysql> insert into t6 values(1,'192.168.150.1',3306);
Query OK, 1 row affected (0.01 sec)
mysql> insert into t6 values(1,'192.168.150.1',3307);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t6 values(1,'192.168.150.2',3307);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t6 values(1,'192.168.150.2',3307);
ERROR 1062 (23000): Duplicate entry '192.168.150.2-3307' for key 'ip'
mysql> create table t7(id int primary key);
Query OK, 0 rows affected (0.04 sec)
mysql> desc t7;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.02 sec)
主键本身是一种索引,索引能够加快查询速度
InnoDB存储引擎规定每一张表都要有一个主键,但是,我之前创建的表都没有指定主键,表是怎么创建成功的?
是因为InnoDB存储引擎内部有一个隐藏的主键,这个主键我们看不到,它也不能够加快查询速度,仅仅是为了帮助我们把表创建成功,所以,以后我们创建表的时候都主动的创建一个主键,我们自己创建的主键能够加快查询速度,因为是一个索引。
一般情况下,主键应该创建id字段,一张表中不只是有一个主键,可以有多个主键,但是,大多数情况下,都只有一个
每一次主动比上一次加一,一般情况下配合主键使用
mysql> create table t8(id int primary key auto_increment,name varchar(32));
Query OK, 0 rows affected (0.03 sec)
mysql> insert into t8(name) values('wzc');
Query OK, 1 row affected (0.01 sec)
mysql> insert into t8(name) values('wzc');
Query OK, 1 row affected (0.00 sec)
mysql> select * from t8;
+----+------+
| id | name |
+----+------+
| 1 | wzc |
| 2 | wzc |
+----+------+
2 rows in set (0.00 sec)
mysql> delete from t8 where id=2;
Query OK, 1 row affected (0.00 sec)
mysql> insert into t8(name) values('wzc');
Query OK, 1 row affected (0.00 sec)
mysql> select * from t8;
+----+------+
| id | name |
+----+------+
| 1 | wzc |
| 3 | wzc |
+----+------+
2 rows in set (0.00 sec)
1.增加字段
mysql> desc t9;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(9) | YES | | NULL | |
| name | varchar(32) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.02 sec)
mysql> alter table t9 add age varchar(32);
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc t9;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(9) | YES | | NULL | |
| name | varchar(32) | YES | | NULL | |
| age | varchar(32) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.02 sec)
mysql> alter table t9 add age varchar(32) after id;# 增加在指定字段后
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc t9;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(9) | YES | | NULL | |
| age | varchar(32) | YES | | NULL | |
| name | varchar(32) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.02 sec)
mysql> alter table t9 add gender varchar(32) first;# 增加在最前面
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc t9;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| gender | varchar(32) | YES | | NULL | |
| id | int(9) | YES | | NULL | |
| age | varchar(32) | YES | | NULL | |
| name | varchar(32) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
4 rows in set (0.01 sec)
2.删除字段
mysql> desc t9;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(9) | YES | | NULL | |
| name | varchar(32) | YES | | NULL | |
| age | varchar(32) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.02 sec)
mysql> alter table t9 drop age;
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc t9;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(9) | YES | | NULL | |
| name | varchar(32) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.02 sec)
4.修改字段名
modify:只能改字段数据类型完整约束,不能改字段名(数据类型可改范围)
change:可以改字段名
mysql> alter table t9 modify age varchar(64);
Query OK, 1 row affected (0.07 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> desc t9;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| gender | varchar(32) | YES | | NULL | |
| id | int(9) | YES | | NULL | |
| age | varchar(64) | YES | | NULL | |
| name | varchar(32) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
4 rows in set (0.02 sec)
mysql> alter table t9 change name hobby varchar(32);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc t9;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| gender | varchar(32) | YES | | NULL | |
| id | int(9) | YES | | NULL | |
| age | varchar(64) | YES | | NULL | |
| hobby | varchar(32) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
4 rows in set (0.02 sec)
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);
1.查询id大于等于3小于等于6的数据
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 |
+----+-------+--------+-----+------------+---------+--------------+----------+--------+-----------+
4 rows in set (0.00 sec)
mysql> select * from emp where id between 3 and 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 |
+----+-------+--------+-----+------------+---------+--------------+----------+--------+-----------+
4 rows in set (0.00 sec)
2.查询薪资是20000或者18000或者17000的数据
mysql> select * from emp where salary = 20000 or salary = 18000 or salary = 17000;
mysql> select * from emp where salary in (20000,18000,17000);
3.查询员工姓名中包含o字母的员工姓名和薪资
在你刚接触mysql查询的时候,建议你按照查询的优先级顺序拼写出你的aql语句
先是查哪张表 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 |
+------+------------+
3 rows in set (0.00 sec)
4.查询员工姓名是由四个字符组成的员工姓名与其薪资
select name,salary from emp where like '____';
mysql> select name,salary from emp where char_length(name) = 4;
5.查询id小于3或者大于6的数据
mysql> select * from emp where id < 3 or id > 6;
mysql> select * from emp where id not between 3 and 6;
6.查询薪资不在20000,18000,17000范围的数据
mysql> select * from emp where salary not in (20000,18000,17000);
7.查询岗位描述为空的员工名与岗位名 针对null不能用等号,只能用is
mysql> select name,post from emp where post_comment is NULL;
分组:按照某个指定的条件将单个单个的个体分成一个个整体
单纯的分组是没有意义的
再MySQL中分组之后,只能够获得分组的依据!按照哪个字段分组就只能获取这个字段的值,别的字段不能拿到
分组一般配合聚合函数使用:sum max min avg count
分组的关键字:group by
1.分组之后默认可以获取所有的字段信息
2.分组之后,展示的数据都是每个组的第一条数据
1.按部门分组
mysql> select * from emp group by post;
mysql> select post from emp group by post;# 查看分组
2.获取每个部门的最高工资
mysql> select post,max(salary) from emp group by post;
补充:在显示的时候还可以给字段取别名
mysql> select post '部门',max(salary) as '最高工资' from emp group by post;
+-----------+--------------+
| 部门 | 最高工资 |
+-----------+--------------+
| operation | 20000.00 |
| sale | 4000.33 |
| teacher | 1000000.31 |
+-----------+--------------+
3 rows in set (0.00 sec)
每个部门的最低工资
mysql> select post,min(salary) from emp group by post;
每个部门的平均工资
mysql> select post,avg(salary) from emp group by post;
每个部门的工资总和
mysql> select post,sum(salary) from emp group by post;
每个部门的人数
mysql> select post,count(id) from emp group by post;
如果真的需要获取分组以外的数据字段,可以使用group_concat(),分组之后使用
每个部门的员工姓名
mysql> select post,group_concat(name) from emp group by post;
+-----------+------------------------------------------------+
| post | group_concat(name) |
+-----------+------------------------------------------------+
| operation | 程咬铁,程咬铜,程咬银,程咬金,僧龙 |
| sale | 拉拉,乐乐,西西,呵呵,哈哈 |
| teacher | sank,jenny,jack,owen,tony,kevin,tom |
+-----------+------------------------------------------------+
3 rows in set (0.00 sec)
mysql> select post,group_concat(name,'|',sex) from emp group by post;
mysql> select post,group_concat(name,'|',sex,'|',post) from emp group by post;
mysql> select post,group_concat(distinct name ) from emp group by post;
+-----------+------------------------------------------------+
| post | group_concat(distinct name ) |
+-----------+------------------------------------------------+
| operation | 程咬铁,程咬铜,程咬银,程咬金,僧龙 |
| sale | 拉拉,乐乐,西西,呵呵,哈哈 |
| teacher | sank,jenny,jack,owen,tony,kevin,tom |
+-----------+------------------------------------------------+
mysql> select post,group_concat(distinct name separator '%') from emp group by post;
concat 不分组使用
mysql> select concat(name,sex) from emp;
+------------------+
| concat(name,sex) |
+------------------+
| tommale |
| kevinmale |
| tonymale |
| owenmale |
| jackfemale |
| jennymale |
| sankmale |
| 哈哈female |
| 呵呵female |
| 西西female |
| 乐乐female |
| 拉拉female |
| 僧龙male |
| 程咬金male |
| 程咬银female |
| 程咬铜male |
| 程咬铁female |
+------------------+
17 rows in set (0.00 sec)
select concat(name,'|', sex) from emp;
concat_ws()
mysql> select post,concat_ws('|',name,age,sex)from emp;
+-----------+-----------------------------+
| post | concat_ws('|',name,age,sex) |
+-----------+-----------------------------+
| teacher | tom|78|male |
| teacher | kevin|81|male |
| teacher | tony|73|male |
| teacher | owen|28|male |
| teacher | jack|18|female |
| teacher | jenny|18|male |
| teacher | sank|48|male |
| sale | 哈哈|48|female |
| sale | 呵呵|38|female |
| sale | 西西|18|female |
| sale | 乐乐|18|female |
| sale | 拉拉|28|female |
| operation | 僧龙|28|male |
| operation | 程咬金|18|male |
| operation | 程咬银|18|female |
| operation | 程咬铜|18|male |
| operation | 程咬铁|18|female |
+-----------+-----------------------------+
17 rows in set (0.00 sec)
where与having都是筛选功能,但是有区别
where在分组之前对数据进行筛选
having在分组之后对数据进行筛选
1.统计各部门年龄在30岁以上的员工平均薪资,并且保留平均薪资大于10000的部门.
先筛选出年龄在30岁以上的
mysql> select * from emp where age > 30;
+----+--------+--------+-----+------------+---------+--------------+------------+--------+-----------+
| 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 |
| 3 | tony | male | 73 | 2014-07-01 | teacher | NULL | 3500.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 |
+----+--------+--------+-----+------------+---------+--------------+------------+--------+-----------+
6 rows in set (0.00 sec)
再进行分组,按照部门分组
mysql> select avg(salary) as avg_salary from emp where age > 30 group by post;
+---------------+
| avg_salary |
+---------------+
| 2500.240000 |
| 255450.077500 |
+---------------+
2 rows in set (0.00 sec)
保留平均薪资大于100000的部门
mysql> select avg(salary) as avg_salary from emp where age > 30 group by post having avg(salary) > 10000;
+---------------+
| avg_salary |
+---------------+
| 255450.077500 |
+---------------+
1 row in set (0.00 sec)
带主键的数据去重有没有意义? 没有,主键本身就是唯一的
mysql> select distinct sex from emp;
+--------+
| sex |
+--------+
| male |
| female |
+--------+
2 rows in set (0.00 sec)
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岁以上的员工
mysql> select * from emp where age >20;
各部门的平均薪资
mysql> select avg(salary) from emp where age > 20 group by post having avg(salary) >1000;
mysql> select avg(salary) from emp where age > 20 group by post having avg(salary) > 1000 order by avg(salary) desc;
限制展示条数
mysql> select * from emp limit 3;
查询工资最高的人的详细信息
mysql> select * from emp order by salary desc limit 1;
分页显示
mysql> select * from emp limit 0,5; # 第一个参数表示起始位置,第二个参数表示的是条数,不是索引位置
mysql> select * from emp where name regexp '^j.*(n|y)$';
+----+-------+------+-----+------------+---------+--------------+----------+--------+-----------+
| id | name | sex | age | hire_date | post | post_comment | salary | office | depart_id |
+----+-------+------+-----+------------+---------+--------------+----------+--------+-----------+
| 6 | jenny | male | 18 | 1900-03-01 | teacher | NULL | 30000.00 | 401 | 1 |
+----+-------+------+-----+------------+---------+--------------+----------+--------+-----------+
1 row in set (0.00 sec)