# IF IF(10>5, '大', '小') SELECT name IF(salary IS NULL, "没薪水", "有薪水")
# CASE 第一种使用 CASE '要判断的表达式' WHEN '常量1' then 值(没有分号) / 表达式(有分号); WHEN '常量2' then 值(没有分号) / 表达式(有分号); WHEN '常量3' then 值(没有分号) / 表达式(有分号); ... ELSE 值(没有分号) / 表达式(有分号); END;
# CASE 第二种语句 CASE WHEN 表达式 then 值(没有分号) / 表达式(有分号); WHEN 表达式 then 值(没有分号) / 表达式(有分号); WHEN 表达式 then 值(没有分号) / 表达式(有分号); ... ELSE 值(没有分号) / 表达式(有分号); END;
8. 数据汇总-聚集函数 AVG, COUNT, MAX, MIN, SUM
运行在行组, 计算和返回单个值的函数.
统计使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# AVG() 针对单列, 对多列需要使用多个 SELECT AVG(age) AS avg_age FROM 表名; # 忽略 NULL
# 聚集不同的值 + DISTINCT # 聚集函数默认ALL SELECT AVG(DISTINCT age) FROM 表名; # 对唯一值求均值 SELECT COUNt(DISTINCT age) FROM 表名; # 对age列的唯一值统计个数
9. 数据分组查询 —— GROUP BY, HAVING
1. GROUP BY 分组字段
如果分组列中具有 NULL, 则NULL 将作为一个分组返回.
2. HAVING 过滤条件 =====WHERE 条件
3. 必加 ORDER BY, 因为G出来的结果不保证排序了.
4. 能where 就不用having
按字段分组
GROUP BY id
按表达式或者函数
GROUP BY length(id) AS len HAVING len>3;
按多个字段分组
1 2 3 4 5
# 分组统计值 SELECT id, COUNT(*) AS num_ FROM 表名 GROUP BY id ORDER BY age;
# 分组过滤 大于2的值 SELECT age FROM 表名 GROUP BY id HAVING COUNT(*)>=2 ORDER BY age;
10. 子查询 IN + 括号
查询的结果作为另一个查询的条件,然后多层嵌套.
内层查询建立一个临时表。费时间.
优化需要用join 联结表替代….
where 和 having 后可放的子查询:
子查询放在小括号内
标量子查询(单值),一般配合单行操作符使用: > < >= = <>
列子查询(单列多行), 一般配合多行操作符使用:
IN 列表中的一个
ANY/SOME
ALL
select 后可以放的子查询:
from 后可以放的子查询:
必须起别名
FROM (子查询表) newtable
1 2 3 4 5 6 7 8 9 10
# 标量子查询 # 1. 谁工资比 elgong 高 SELECT * FROM employee WHERE salary>(select salary from emplot WHERE name = 'elgong');
# 查询超过平均工资的员工信息 select avg(sal) from emp; /* avg(sal)=2000 */ select * from emp where sal >= 2000; /* 子查询方法 */ select * from emp where sal >= (select avg(sal) from emp);
11. 连接查询——JOIN 联结表 ( INNER JOIN, LEFT JOIN, RIGHT JOIN)
注意判断驱动表是哪个? 查询计划 explain
正常情况下,from 后的表是驱动表,但是当出现下面情况,驱动表变成了 class。
分析: 当 where 后的条件使得表之间数据多少不一样时,数据少的为主表
小表驱动大表的原则
select * from student left join class on class.classid = student.classid where class.classid = 2;
概念: 联结指两张表,或者多张表之间组合在一起进行查询, 是在运行时做的操作;
left JOIN (左联结)保证读取主表的全部数据
right JOIN (右联结) 保证读取主表的全部数据
inner JOIN (内部联结,等值联结) 只读取共有的数据
自联结: 常用来代替从同一个表检索数据的子查询. FROM table1 AS t1, table2 AS t2, WHERE t1.col = t2.col;
FROM table1 AS t1, table2 AS t2, table3 AS t3 WHERE t1.col = t2.col AND t2.c = t3.c ;
自连接(单表)
同表不同名
FROM employees e1, employees e2 WHERE e1.id = e2.iidd
SQL99语法
SELECT 查询列表
FROM 表1 别名 [连接类型] join 表2 别名 on 连接条件
内连接 inner join
外连接 left, right
主表全部显示
从表中没有与主表匹配的结果,显示NULL
等价于==== 内连接结果 + 主表有而从表没有的记录
左外和右外,交换表顺序可以等价效果
全外连接 full join
交叉连接 cross join
笛卡尔乘机
非等值连接
FROM e join g on e.salary BETWEEN g.low AND g.upper
自连接
一样的join on 不同名的同一张表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# 创建联结表的两种方式 # 1. 等值连接 WHERE 表1.id = 表2.id AND 表2.size = 表3.size SELECT vendors.vendor_name, product.prod_name, product.prod_price FROM product,vendors WHERE vendors.vendor_id = product.vendor_id ORDER BY vendor_name;
# 2.内部联结(等值联结) 表的键数量相同 FROM 表1 INNER JOIN 表2 ON 表1.id = 表2.id SELECT v.vendor_name, p.prod_name, p.prod_price FROM product AS p INNER JOIN vendors AS v ON v.vendor_id = p.vendor_id ORDER BY v.vendor_name;
# # 对联结的表使用聚合方法 待补充.....
12. 分页查询
LIMIT 行X(从0开始), size;
LIMIT size OFFSET size;
当要显示的数据,需要分页显示
从行0开始
从第四行开始,检索5行
LIMIT 3, 5
LIMIT 5 OFFSET 3
1 2 3 4 5 6 7 8
# 查询前5条数据 SELECT * FROM employees LIMIT 0, 5; # 查询11到25条数据 SELECT * FROM employees LIMIT 10, 25-11+1;
# 计算公式 LIMIT (page-1)*size, size;
13. 联合查询 union (自动去重,union all 不去重)
将多条查询语句合并成一个结果
特点:
查询 列数 和 列顺序 必须一致
自动去重
不去重 union all
1 2 3
SELECT * FROM e1 WHERE UNION SELECT * FROM e1 WHERE
14. 视图
视图是虚拟的表, 是对其基表的封装.
使用的好处:
重用 SQL 语句
使用表的部分,即过滤掉部分数据
限制:
图名唯一
视图可以嵌套
视图的ORDER BY 次于 从该视图检索数据的ORDER
视图可以和表一起使用
1 2 3
# 创建视图 CREATE VIEW viewname AS SELECT * FROM table WHERE id!=1;