目录
一、聚合函数
聚合函数:SQL已经定义好的函数,在查询语句中可以直接使用
以emp表为例,创建emp表
CREATE TABLE emp(
empno INT,
ename VARCHAR(50),
job VARCHAR(50),
mgr INT,
hiredate DATE,
sal DECIMAL(7,2),
comm decimal(7,2),
deptno INT
) ;
INSERT INTO emp values(7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20);
INSERT INTO emp values(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30);
INSERT INTO emp values(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30);
INSERT INTO emp values(7566,'JONES','MANAGER',7839,'1981-04-02',2975,NULL,20);
INSERT INTO emp values(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30);
INSERT INTO emp values(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,NULL,30);
INSERT INTO emp values(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,NULL,10);
INSERT INTO emp values(7788,'SCOTT','ANALYST',7566,'1987-04-19',3000,NULL,20);
INSERT INTO emp values(7839,'KING','PRESIDENT',NULL,'1981-11-17',5000,NULL,10);
INSERT INTO emp values(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30);
INSERT INTO emp values(7876,'ADAMS','CLERK',7788,'1987-05-23',1100,NULL,20);
INSERT INTO emp values(7900,'JAMES','CLERK',7698,'1981-12-03',950,NULL,30);
INSERT INTO emp values(7902,'FORD','ANALYST',7566,'1981-12-03',3000,NULL,20);
INSERT INTO emp values(7934,'MILLER','CLERK',7782,'1982-01-23',1300,NULL,10);
count(指定列):统计指定列不为null的行数
注意:在SQL中任何数和NULL相加结果仍然是NULL。若需要将数值型数据和NULL相加,则需要先将NULL转换为0,然后相加,转换函数是IFNULL(列名,0)
eg:统计emp表中的记录数
-- 统计emp表中的记录数(应用聚合函数)
select count(*) as '总记录数' from emp;
-- 查询emp表中有奖金的人数
select count(comm) as '奖金人数' from emp; -- 列值null 和 列值0 是不同的
-- 查询emp表中月薪大于2500的人数(查询中带有where子句)
select count(*) as '月薪大于2500的人数' from emp where sal > 2500;
-- 统计月薪与佣金之和大于2500的人数
select count(*) as '月薪与佣金之和大于2500的人数' from emp
where sal+ifnull(comm,0)>2500; -- ifnull(comm,0)是讲comm为null转化成0再进行相加
1、求和sum
sum(指定列名):求和函数
-- 查询所有雇员月薪之和
select sum(sal) as '总工资' from emp;
-- 查询所有雇员月薪之和,以及所有雇员佣金之和
select sum(sal) as '总工资', sum(comm) as '总奖金' from emp;
-- 查询所有雇员月薪+佣金之和
select sum(sal+ifnull(comm,0)) as '月薪与佣金之和' from emp;
2、平均值avg
avg(指定列名):求平均值
-- 统计所有员工的平均工资
select sum(sal) as '总工资',
count(*) as '员工人数',
avg(sal) as '平均工资'
from emp;
3、最大最小值
max(列名):求最大值 min (列名):求最小值
-- 查询最高工资和最低工资
select max(sal) as '最高工资',min(sal) as '最低工资' from emp;
二、分组语句
1、group by
分组语句:将查询结果进行分组,使用group by子句
-- 分组查询
-- 查询每个部门的部门编号以及每个部门的工资和
select deptno,sum(sal)
from emp
group by deptno;
-- 查询每个部门的部门编号以及部门人数
select deptno,count(*)
from emp
group by deptno;
-- 查询每个部门的部门编号以及部门员工工资大于1500的人数
select deptno,count(*)
from emp
where sal>1500
group by deptno;
2、having子句
having子句:必须和group by子句结合使用,作用是对分组的结果再进行筛选
-- having子句
-- 查询总工资大于9000的部门编号以及工资和
select deptno,sum(sal)
from emp
group by deptno -- 每个部门编号分组,计算每个部门的工资总和
having sum(sal)>9000; -- 对分组的结果进行筛选
三、分页查询
LIMIT:用来限定查询结果的起始行,以及总行数
limit 起始行索引,连续查询的总行数。eg:limit 0,5 表示从第一行(索引为0)开始,查询5行
-- 分页查询,每页显示五条记录
-- 第一页
select * from emp
limit 0,5; -- 第一页。0行开始每页五条记录
-- 第二页
select * from emp
limit 5,5;
-- 第三页
select * from emp
limit 10,5;
第一页:
第二页:
第三页:
四、多表连接查询
多表连接查询:在一个查询语句中显示多张表的数据。
在xy数据库中建立两张表分别命名为cstudent、mstudent
create table cstudent(
id int primary key,
name varchar(50),
sex varchar(2)
);
INSERT INTO `xy`.`cstudent` (`id`, `name`, `sex`) VALUES ('1001', '张三丰', '男');
INSERT INTO `xy`.`cstudent` (`id`, `name`, `sex`) VALUES ('1002', '张君宝', '男');
INSERT INTO `xy`.`cstudent` (`id`, `name`, `sex`) VALUES ('1003', '郭襄', '女');
create table mstudent(
id int primary key,
name varchar(50),
sex varchar(2)
);
INSERT INTO `xy`.`mstudent` (`id`, `name`, `sex`) VALUES ('2002', '宋江', '男');
INSERT INTO `xy`.`mstudent` (`id`, `name`, `sex`) VALUES ('2003', '燕青', '男');
INSERT INTO `xy`.`mstudent` (`id`, `name`, `sex`) VALUES ('2004', '扈 三娘', '女');
1、并集
并:并操作是把具有相同字段数目和字段类型的两个或多个表合并到一起;并集:union
-- 多表连接查询 并集(两张以上的表,字段数目和字段类型必须完全相同)
-- 连接cstuednt、mstudent
select * from cstudent
union
select * from mstudent
2、笛卡尔积
-- 多表连接查询 笛卡尔积(一张表中的一条记录对应另一张表的每一条记录)
select * from cstudent,mstudent;
3、连接查询
连接查询:join,本质是对笛卡尔积进行筛选
在xy数据库中创建interest表
create table interest(
id int primary key,
dance varchar(45),
foot varchar(45),
base varchar(45)
);
INSERT INTO `xy`.`interest` (`id`, `dance`, `foot`, `base`)
VALUES ('1001', '拉丁', '跑步', '篮球');
INSERT INTO `xy`.`interest` (`id`, `dance`, `foot`, `base`)
VALUES ('1002', '街舞', '慢步', '足球');
INSERT INTO `xy`.`interest` (`id`, `dance`, `foot`, `base`)
VALUES ('1011', '肚皮', '游泳', '羽毛球');
INSERT INTO `xy`.`interest` (`id`, `base`)
VALUES ('1022', '排球');
(1)内连接
内连接(inner join):保留关系中所匹配的数据记录,舍弃不匹配的纪录,也称为等值连接,返回的是两张表都满足条件的部分(where条件)
-- 在cstudent表和interest表上建立内连接(等值连接)
select a.id,a.name,a.sex,b.dance,b.base,b.foot
from cstudent as a-- 给cstudent一个别名为a
inner join interest as b -- 内连接到interest并给interest一个别名为b
on a.id = b.id -- 等值连接
(2)外连接(outer join)
A、左外连接(左连接):left outer join ... on ...可以简写为left join ... on ...保留左表中的所有记录,右表中没有匹配的记录显示为NULL
-- 给cstudent表中添加数据
INSERT INTO `xy`.`cstudent` (`id`, `name`, `sex`) VALUES ('1004', '刘备', '男');
INSERT INTO `xy`.`cstudent` (`id`, `name`, `sex`) VALUES ('1005', '张飞', '男');
INSERT INTO `xy`.`cstudent` (`id`, `name`, `sex`) VALUES ('1006', '关于', '男');
INSERT INTO `xy`.`cstudent` (`id`, `name`, `sex`) VALUES ('1007', '小乔', '女');
INSERT INTO `xy`.`cstudent` (`id`, `name`, `sex`) VALUES ('1008', '黄蓉', '女');
-- 左外连接, 在cstudent表和interest表上通过id建立左连接
-- 左连接保留左表中的所有记录,右表中没有匹配的记录显示为null
select a.id,a.name,a.sex,b.dance,b.base,b.foot
from cstudent as a-- 给cstudent一个别名为a
left join interest as b -- 左连接到interest并给interest一个别名为b
on a.id = b.id;
B、右外连接(右连接):right outer join ... on ...可以简写为right join ... on ...保留右表中的所有记录,左表中没有匹配的记录显示为NULL
-- 右外连接, 在cstudent表和interest表上通过id建立右连接
-- 右连接保留右表中的所有记录,左表中没有匹配的记录显示为null
select a.id,a.name,a.sex,b.dance,b.base,b.foot
from cstudent as a-- 给cstudent一个别名为a
right join interest as b -- 右连接到interest并给interest一个别名为b
on a.id = b.id;
C、全外连接(full join) :在表的笛卡尔积中,除了选择相匹配的数据记录,还会包含左右两边表中不匹配的所有数据记录
(3)交叉连接
交叉连接(cross join)
-- 交叉连接, 在cstudent表和interest表上通过id建立交叉连接
select a.id,a.name,a.sex,b.dance,b.base,b.foot
from cstudent as a
cross join interest as b
on a.id = b.id;