1、排序(order by)
select *
from stu
order by age; -- 默认升序
升序 ASC 降序DESC
-- DESC 具有查看表的结构的功能
desc stu; 不同于oracle,可以在查询窗口使用,oracle只能在命令窗口使用
例题:
按年龄升序
SELECT *
FROM stu
ORDER BY age ASC;
按年龄降序
SELECT *
FROM stu
ORDER BY age DESC;
按奖金降序,奖金相同按id升序
SELECT *
FROM stu
ORDER BY tuition DESC,sid ASC;
按第六列降序排序(相对位置排序)
select *
from emp
order by 6 desc;
2、常用的聚合函数
函数:做某些事情的方法
聚合:把多个值变成一个值
count(): 计数,不计算null值,统计指定列不为NULL的记录行数;
max(): 求最大值,若为字符串类型,按字符串排序运算
min(); 求最小值,若为字符串类型,按字符串排序运算
sum(): 求和,不是数值类型则为0
avg(): 求平均,不是数值类型则为0
例题:
-- 当需要纵向统计时可以使用COUNT(),查询emp表中记录数:
SELECT COUNT(*) '记录数'
FROM emp;
-- 查询emp表中有佣金的人数:
SELECT COUNT(*) '有佣金的人数'
FROM emp
WHERE comm IS NOT NULL;
SELECT COUNT(comm) '有佣金的人数' -- 处理非空数据
FROM emp;
-- 查询emp表中月薪大于2500的人数:
SELECT count(*)
FROM emp
WHERE sal>2500;
-- 统计月薪与佣金之和大于2500元的人数:
SELECT COUNT(*)
FROM emp
WHERE sal+IFNULL(comm,0) > 2500;
-- 查询有佣金的人数以及有领导的人数:
SELECT COUNT(comm) '有佣金的人数', COUNT(mgr) '有领导的人数'
FROM emp
-- 需要纵向求和时使用sum()函数。
-- 查询所有雇员月薪和:
SELECT SUM(sal)
FROM emp;
-- 查询所有雇员月薪和,以及所有雇员佣金和:
SELECT SUM(sal),SUM(comm)
FROM emp;
-- 查询所有雇员月薪+佣金和:
SELECT SUM(sal+IFNULL(comm,0))
FROM emp;
SELECT SUM(sal) + SUM(COMM)
FROM emp;
-- 统计所有员工平均工资:
SELECT AVG(sal) '平均工资' -- 有工资的平均工资,假如没工资就不算进去
FROM emp;
SELECT SUM(sal)/COUNT(*) -- 具体业务具体分析
FROM emp;
-- 查询最高工资和最低工资:
SELECT MAX(sal) '最高工资', MIN(sal) '最低工资'
FROM emp;
SELECT COUNT(0)
FROM dual; -- 1
select sum(sname) from stu; -- 0,字符串求和为0
3、分组
-- 分组查询group by
-- select 后面只能写聚合函数和分组的参照列
例题:
查询每个部门的部门编号和每个部门的工资和:
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;
having
having:跟where一样都是进行过滤,区别在于where在分组前处理分组前的条件
having在分组后处理分组后的条件
where 后面不能使用聚合函数 而having可以
例题:
查询工资总和大于9000的部门编号以及工资和:
SELECT deptno, SUM(sal) FROM emp GROUP BY deptno HAVING SUM(sal) > 9000;
4、分页查询
-- LIMIT num1(从哪里开始),num2(展示多少数据)
SELECT *
FROM emp
LIMIT 5,5; -- 1006-1010
-- LIMIT NUM: 默认从0开始查看num条记录
SELECT *
FROM emp
LIMIT 5
-------------------------------------------------------------------------------------------------------------
5、union
CREATE TABLE t1(
a INT,
b VARCHAR(10)
);
CREATE TABLE t2(
c INT,
d VARCHAR(10)
);
INSERT INTO t1 VALUES
(1,'a'),(2,'b'),(3,'c'),(4,'d');
INSERT INTO t2 VALUES
(4,'d'),(5,'e'),(6,'g');
-- UNION合并结果集
-- 第二句的结果去掉列名拼在第一条语句的下面
-- 默认去除重复的记录,不排序
-- 要求两条语句列数相同并且对应的数据类型一致
例题:
SELECT *
FROM t1
UNION
SELECT *
FROM t2;
-- UNION ALL 合并结果集不去重
SELECT * FROM t1
UNION ALL
SELECT * FROM t2;
6、连接查询(多表查询)
-- 连接查询
SELECT *
FROM t1,t2; -- 产生大量笛卡尔积
-- 等值连接
-- 一般是通过主外键相等的关系消除笛卡尔积
-- 主键:一条记录的唯一身份标识(1.不能为空 2.不能重复)
-- 外键:跟另外一张表建立联系列(一定是另外一张表的主键)
SELECT *
FROM emp,dept
WHERE emp.deptno=dept.deptno;
-- 内连接
SELECT *
FROM emp INNER JOIN dept
ON emp.deptno = dept.deptno;
-- INNER 可以省略
-- 等值连接和内连接不满足等值条件的不会显示出来(被过滤掉了)
-- 外连接
-- 主表不满足条件的会显示出来,从表用null值匹配,从表不满足条件的不会显示出来
-- 左外连接 LEFT JOIN ... ON
SELECT *
FROM emp LEFT OUT JOIN dept
ON emp.deptno = dept.deptno;
-- 关键字outer可以省略
-- 右外连接
SELECT *
FROM emp RIGHT OUTER JOIN dept
ON emp.deptno = dept.deptno;
-- 自然连接
-- 不需要手动指定等值关系,系统会根据同名的列进行等值匹配,
-- 同名列合并,居左显示(同名列,主表内容,从表内容)
-- 自然连接内的内连接
SELECT * FROM emp NATURAL JOIN dept;
-- 自然连接内的左连接
SELECT * FROM emp NATURAL LEFT JOIN dept;
-- 自然连接内的右连接
SELECT * FROM emp NATURAL RIGHT JOIN dept;
-- n张表至少需要n-1个连接
-- 子查询
-- 子查询-单行单列
1. 工资高于甘宁的员工。
SELECT ename
FROM emp
WHERE sal > (SELECT sal FROM emp WHERE ename = '甘宁');
-- 子查询-多行单列:
2.工资高于30部门所有人工资 -- ALL所有 ANY任意(比其中一个大)
SELECT ename,sal
FROM emp
WHERE sal > ALL (SELECT sal FROM emp WHERE deptno=30)
-- 子查询-单行多列:
查询工作和工资与殷天正完全相同的员工信息分析:
SELECT *
FROM emp
WHERE (job,sal)=(SELECT job, sal FROM emp WHERE ename='殷天正')
AND ename!='殷天正';
-- 子查询-多行多列(1)
查询员工编号为1006的员工名称、员工工资、部门名称、部门地址
SELECT e.ename,e.sal,d.dname, d.loc
FROM (SELECT empno,ename,sal,deptno FROM emp) e JOIN dept d on e.deptno=d.deptno
WHERE e.empno = 1006
7、 完整性约束-主键
-- 主键:一条记录的唯一身份标识(1.不能为空 2.不能重复)
-- 创建表的时候指定主键
CREATE TABLE test2(
sid INT PRIMARY KEY,
sname VARCHAR(20)
);
-- 表已经创建则通过修改表去添加主键
ALTER TABLE test1 ADD PRIMARY KEY(sid);
-- 删除主键
-- 非空属性还是存在
ALTER TABLE test2 DROP PRIMARY KEY;
-- 主键自增 auto_increment根据最后一个数字开始自增长
-- oracle无此特性, oracle引入序列的对象
CREATE TABLE test3(
sid INT PRIMARY KEY auto_increment,
sname VARCHAR(10)
);
SELECT * FROM test3;
--去除自增属性
-- CHANGE一定要改列的名字
ALTER TABLE test3 CHANGE sid sid INT; -- 后面这个sid可以改名 id
-- MODIFY 不用改名字
ALTER TABLE test3 MODIFY sid INT;
-- UNION 唯一约束 -- 非空约束 NOT NULL
CREATE TABLE test4(
sid INT,
sname VARCHAR(10) UNIQUE,
age VARCHAR(10) NOT NULL
);
-- 外键约束
-- 将t_section中的master_id列设置成关联t_user 表uid 的外键
创建t_section表,指定sid为主键列,u_id为相对t_user表的uid列的外键:
CREATE TABLE t_section(
sid INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR(30),
u_id INT,
CONSTRAINT fk_t_user FOREIGN KEY(u_id) REFERENCES t_user(uid)
);
修改t_section表,指定u_id为相对t_user表的uid列的外键:
ALTER TABLE t_section ADD CONSTRAINT fk_t_user FOREIGN KEY(u_id) REFERENCES t_user(uid);
修改t_section表,删除u_id的外键约束:
ALTER TABLE t_section DROP FOREIGN KEY fk_t_user;