什么是Mysql?
mysql 是一个开源的关系型数据库管理系统,现在是 oracle 公司旗下的一款产品,由 C 和 C++ 语言编写,可移植性高。支持 在多种操作系统上安装,最常见有AIX , linux , window 。 mysql 因为开源免费,所以受到了目前互联网行业的欢迎。
MySql的各个版本
MySQL Community Server 社区版本,开源免费,但不提供官方技术支持。
MySQL Enterprise Edition 企业版本,需付费,购买了之后可以电话支持
MySQL Cluster 集群版,开源免费。可将几个 MySQL Server 封装成一个 Server 。
Mysql操作语句分类
DDL 数据定义语言 (Data Defifinition Language) 例如:建库,建表
DML 数据操纵语言 (Data Manipulation Language) 例如:对表中的数据进行增删改操作
DQL 数据查询语言 (Data Query Language) 例如:对数据进行查询
DCL 数据控制语言 (Data Control Language) 例如:对用户的权限进行设置
下面以这三个表为例
-- ----------------------------
-- Table structure for dept
-- ----------------------------
DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept` (
`deptnu` int NOT NULL COMMENT '部门编号',
`dname` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '部门名称',
`addr` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '部门地址',
PRIMARY KEY (`deptnu`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of dept部门表
-- ----------------------------
INSERT INTO `dept` VALUES (10, '研发部', '北京');
INSERT INTO `dept` VALUES (20, '工程部', '上海');
INSERT INTO `dept` VALUES (30, '销售部', '广州');
INSERT INTO `dept` VALUES (40, '财务部', '深圳');
-- ----------------------------
-- Table structure for employee
-- ----------------------------
DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee` (
`empno` int NOT NULL COMMENT '雇员编号',
`ename` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '雇员姓名',
`job` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '雇员职位',
`mgr` int NULL DEFAULT NULL COMMENT '雇员上级编号',
`hiredate` date NULL DEFAULT NULL COMMENT '雇佣日期',
`sal` decimal(7, 2) NULL DEFAULT NULL COMMENT '薪资',
`deptnu` int NULL DEFAULT NULL COMMENT '部门编号',
PRIMARY KEY (`empno`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of employee人员表
-- ----------------------------
INSERT INTO `employee` VALUES (1009, '唐僧', '董事长', NULL, '2010-11-17', 50000.00, 10);
INSERT INTO `employee` VALUES (1004, '猪八戒', '经理', 1009, '2001-04-02', 29750.00, 20);
INSERT INTO `employee` VALUES (1006, '猴子', '经理', 1009, '2011-05-01', 28500.00, 30);
INSERT INTO `employee` VALUES (1007, '张飞', '经理', 1009, '2011-09-01', 24500.00, 10);
INSERT INTO `employee` VALUES (1008, '诸葛亮', '分析师', 1004, '2017-04-19', 30000.00, 20);
INSERT INTO `employee` VALUES (1013, '林俊杰', '分析师', 1004, '2011-12-03', 30000.00, 20);
INSERT INTO `employee` VALUES (1002, '牛魔王', '销售员', 1006, '2018-02-20', 16000.00, 30);
INSERT INTO `employee` VALUES (1003, '程咬金', '销售员', 1006, '2017-02-22', 12500.00, 30);
INSERT INTO `employee` VALUES (1005, '后裔', '销售员', 1006, '2011-09-28', 12500.00, 30);
INSERT INTO `employee` VALUES (1010, '韩信', '销售员', 1006, '2018-09-08', 15000.00, 30);
INSERT INTO `employee` VALUES (1012, '安琪拉', '文员', 1006, '2011-12-03', 9500.00, 30);
INSERT INTO `employee` VALUES (1014, '甄姬', '文员', 1007, '2019-01-23', 7500.00, 10);
INSERT INTO `employee` VALUES (1011, '妲己', '文员', 1008, '2018-05-23', 11000.00, 20);
INSERT INTO `employee` VALUES (1001, '小乔', '文员', 1013, '2018-12-17', 8000.00, 20);
-- ----------------------------
-- Table structure for salgrade
-- ----------------------------
DROP TABLE IF EXISTS `salgrade`;
CREATE TABLE `salgrade` (
`grade` int NOT NULL COMMENT '等级',
`lowsal` int NULL DEFAULT NULL COMMENT '最低薪资',
`higsal` int NULL DEFAULT NULL COMMENT '最高薪资',
PRIMARY KEY (`grade`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of salgrade工资表
-- ----------------------------
INSERT INTO `salgrade` VALUES (1, 7000, 12000);
INSERT INTO `salgrade` VALUES (2, 12010, 14000);
INSERT INTO `salgrade` VALUES (3, 14010, 20000);
INSERT INTO `salgrade` VALUES (4, 20010, 30000);
INSERT INTO `salgrade` VALUES (5, 30010, 99990);
SET FOREIGN_KEY_CHECKS = 1;
1.1 Mysql查询子句之一where查询
简单查询
/*查询人员表信息*/
select * from employee;
/*查询人员表empno,ename,job信息,并给job起别名*/
select empno,ename,job as ename_job from employee;
精确条件查询
/*查询人员为后裔的人*/
select * from employee where ename='后裔';
/*查询工资不为50000的人*/
select * from employee where sal != 50000;
/*查询工资等于50000的人!!!mysql8应该不支持这么写,<>可替换成=*/
select * from employee where sal <> 50000;
/*查询工资大于10000的人*/
select * from employee where sal > 10000;
模糊条件查询
/*ename字段林开头的都会被查询出来*/
select * from employee where ename like '林%';
/*ename字段包含林的都会被查询出来*/
select * from employee where ename like '%林%';
范围查询
/*范围查询函数BETWEEN,查询工资在10000-20000之间的信息*/
SELECT * from employee WHERE sal BETWEEN 10000 and 20000;
select * from employee where hiredate BETWEEN '2011-01-01' and '2017-12-1';
离散查询
/*in查询,查询指定内容的信息*/
SELECT * from employee WHERE ename in ('韩信','妲己')
清除重复值
/*清除字段中重复的信息,只显示一个*/
SELECT DISTINCT(job) from employee;
统计查询(聚合函数)
/*统计数据条数*/
select COUNT(*) from employee;
/*求和函数*/
select SUM(sal) from employee;
/*计算最大值*/
select * from employee where sal= (select max(sal) from employee);
/*求平均值*/
select avg(sal) from employee;
/*计算最小值*/
select * from employee where sal = (select min(sal) from employee);
/*concat 起到连接作用*/
select concat(ename,' 是 ', sal) as aaa from employee;
1.2Mysql查询子句之二grop by分组查询(分组)
作用:把行 按 字段 分组
语法: group by 列 1 ,列 2.... 列 N
适用场合:常用于统计场合,一般和聚合函数连用
/*统计每个部门内有几个人*/
select deptnu,count(*) from employee group by deptnu;
/*统计各个部门的职位及人数*/
select deptnu,job,count(*) from employee group by deptnu,job;
/*统计各个职位的人数*/
select job,count(*) from employee group by job;
1.3Mysql查询子句之三having条件查询(筛选)
作用:对查询的结果进行筛选操作
语法: having 条件 或者 having 聚合函数 条件
适用场合:一般跟在 group by 之后
/*使用grop by统计完后,使用having筛选统计完后的结果*/
select job,count(*) from employee group by job having job ='文员';
/*查询总数大于2的数据*/
select deptnu,job,count(*) from employee group by deptnu,job having count(*)>=2;
/*与第二个意思相同,这个增加了别名*/
select deptnu,job,count(*) as 总数 from employee group by deptnu,job having 总数>=2;
1.4Mysql查询子句之三order by排序查询(排序)
作用:对查询的结果进行排序操作
语法: order by 字段 1, 字段 2 .....
适用场合:一般用在查询结果的排序
/*按照工资排序*/
select * from employee order by sal;
/*按照日期排序*/
select * from employee order by hiredate;
/*查询职位人数大于2的部门,并进行降序排序*/
select deptnu,job,count(*) as 总数 from employee group by deptnu,job having 总数>=2 order by deptnu desc;
/*查询员职位人数大于2的部门,并进行生序排序*/
select deptnu,job,count(*) as 总数 from employee group by deptnu,job having 总数>=2 order by deptnu asc;
/**/
select deptnu,job,count(*) as 总数 from employee group by deptnu,job having 总数>=2 order by deptnu;
顺序:---- where ---- group by ----- having ------ order by
1.5Mysql查询子句之五limit限制查询(限制)
作用:对查询结果起到限制条数的作用
语法: limit n , m n: 代表起始条数值,不写默认为 0 ; m 代表:取出的条数
适用场合:数据量过多时,可以起到限制作用
/*从第四条开始查询5条数据*/
select * from employee limit 4,5;
1.6Mysql查询之exists型子查询
exists 型子查询后面是一个受限的 select 查询语句
exists 子查询,如果 exists 后的内层查询能查出数据,则返回 TRUE 表示存在;为空则返回 FLASE 则不存在。
/*分为俩种:exists跟 not exists*/
select 1 from employee where 1=1;
select * from 表名 a where exists (select 1 from 表名2 where 条件);
/*查询出公司有员工的部门的详细信息*/
select * from dept a where exists (select 1 from employee b where a.deptnu=b.deptnu);
select * from dept a where not exists (select 1 from employee b where a.deptnu=b.deptnu)
1.7Mysql查询之左连接查询与右连接查询
左连接称之为左外连接 右连接称之为右外连接 这俩个连接都是属于外连接
左连接关键字: left join 表名 on 条件 / left outer 表名 join on 条件 右连接关键字: right join 表名 on 条件 /right outer 表名 join on 条件
左连接说明: left join 是 left outer join 的简写,左 ( 外 ) 连接,左表 (a_table) 的记录将会全部表示出来, 而右表 (b_table)只会显示符合搜索条件的记录。右表记录不足的地方均为 NULL 。
右连接说明: right join 是 right outer join 的简写,与左 ( 外 ) 连接相反,右 ( 外 ) 连接,左表 (a_table) 只会显示符合搜索条件的记录,而右表(b_table) 的记录将会全部表示出来。左表记录不足的地方均为 NULL 。
/*eg:列出部门名称和这些部门的员工信息,同时列出那些没有的员工的部门 dept,employee*/
select a.dname,b.* from dept a left join employee b on a.deptnu=b.deptnu;
select b.dname,a.* from employee a right join dept b on b.deptnu=a.deptnu;
1.8Mysql查询之内连接查询与联合查询
内连接:获取两个表中字段匹配关系的记录
主要语法: INNER JOIN 表名 ON 条件 ;
/*查出员工张飞的所在部门的地址*/
select a.addr from dept a inner join employee b on a.deptnu=b.deptnu and b.ename='张 飞';
select a.addr from dept a,employee b where a.deptnu=b.deptnu and b.ename='张飞';
联合查询:就是把多个查询语句的查询结果结合在一起
主要语法 1 : ... UNION ... (去除重复) 主要语法 2 : ... UNION ALL ... (不去重复)
union 查询的注意事项:
(1) 两个 select 语句的查询结果的 “ 字段数 ” 必须一致;
(2) 通常,也应该让两个查询语句的字段类型具有一致性;
(3) 也可以联合更多的查询结果;
(4) 用到 order by 排序时,需要加上 limit (加上最大条数就行),需要对子句用括号括起来
/*对销售员的工资从低到高排序,而文员的工资从高到低排序*/
(select * from employee a where a.job = '销售员' order by a.sal limit 999999 ) union (select * from employee b where b.job = '文员' order by b.sal desc limit 999999);
练习题:
查出至少有一个员工的部门。显示部门编号、部门名称、部门位置、部门人数。
涉及表: employee dept
语句:select deptnu,count(*) from employee group by deptnu
语句:select a.deptnu,a.dname,a.addr, b.zongshu from dept a,(select deptnu,count(*) as zongshu from employee group by deptnu) b where a.deptnu=b.deptnu;
列出薪金比安琪拉高的所有员工
涉及表:employee
语句:select * from employee where sal > (select sal from employee where ename='安琪拉');
列出所有员工的姓名及其直接上级的姓名
涉及表:employee
语句:select a.ename,ifnull(b.ename,'BOSS') as leader from employee a left join employee b on a.mgr=b.empno;
列出受雇日期早于直接上级的所有员工的编号、姓名、部门名称
涉及表:employee dept
语句:select a.empno,a.ename,c.dname from employee a left join employee b on a.mgr=b.empno left join dept c on a.deptnu=c.deptnu where a.hiredate < b.hiredate;
列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门
涉及表:dept employee
语句:select a.dname,b.* from dept a left join employee b on a.deptnu=b.deptnu;
列出所有文员的姓名及其部门名称,所在部门的总人数
涉及表:employee dept
条件:job='文员'
语句:select deptnu,count(*) as zongshu from employee group by deptnu; 语句:select b.ename,a.dname,b.job,c.zongshu from dept a ,employee b ,(select deptnu,count(*) as zongshu from employee group by deptnu) c where a.deptnu=b.deptnu and b.job='文员' and b.deptnu=c.deptnu;