DQL:查询表中的记录

select * from 表名;
1. 语法:
	select
		字段列表
	from
		表名列表
	where
		条件列表
	group by
		分组字段
	having
		分组之后的条件
	order by
		排序
	limit
		分页限定
2. 基础查询
	1. 多个字段的查询
		select 字段名1,字段名2... from 表名;
		注意:
		  如果查询所有字段,则可以使用*来替代字段列表。
	2. 去除重复:
		distinct
	3. 计算列
		一般可以使用四则运算计算一些列的值。(一般只会进行数值型的计算)
		ifnull(表达式1,表达式2)null参与的运算,计算结果都为null
			表达式1:哪个字段需要判断是否为null
			如果该字段为null后的替换值。
	4. 起别名:
		as:as也可以省略
3. 条件查询
	1. where子句后跟条件
	2. 运算符
		><<=>==<>
		BETWEEN...AND  
		IN( 集合) 
		LIKE:模糊查询
			占位符:
				_:单个任意字符
				%:多个任意字符
		IS NULL  
		and  或 &&
		or  或 || 
		not  或 !
	-- 查询年龄大于20岁
	SELECT * FROM student WHERE age > 20;
	SELECT * FROM student WHERE age >= 20;
	-- 查询年龄等于20岁
	SELECT * FROM student WHERE age = 20;
	-- 查询年龄不等于20岁
	SELECT * FROM student WHERE age != 20;
	SELECT * FROM student WHERE age <> 20;
	-- 查询年龄大于等于20 小于等于30
	SELECT * FROM student WHERE age >= 20 &&  age <=30;
	SELECT * FROM student WHERE age >= 20 AND  age <=30;
	SELECT * FROM student WHERE age BETWEEN 20 AND 30;
	-- 查询年龄22岁,18岁,25岁的信息
	SELECT * FROM student WHERE age = 22 OR age = 18 OR age = 25
	SELECT * FROM student WHERE age IN (22,18,25);
	-- 查询英语成绩为null
	SELECT * FROM student WHERE english = NULL; -- 不对的。null值不能使用 =!=) 判断
	SELECT * FROM student WHERE english IS NULL;
	-- 查询英语成绩不为null
	SELECT * FROM student WHERE english  IS NOT NULL;
	-- 查询姓马的有哪些? like
	SELECT * FROM student WHERE NAME LIKE '马%';
	-- 查询姓名第二个字是化的人
	SELECT * FROM student WHERE NAME LIKE "_化%";
	-- 查询姓名是3个字的人
	SELECT * FROM student WHERE NAME LIKE '___';		
    -- 查询姓名中包含德的人
	SELECT * FROM student WHERE NAME LIKE '%德%';

DQL:查询语句进阶

1. 排序查询
	语法:order by 子句
		order by 排序字段1 排序方式1 ,  排序字段2 排序方式2...
	排序方式:
		ASC:升序,默认的。
		DESC:降序。
	注意:
		如果有多个排序条件,则当前边的条件值一样时,才会判断第二条件。
2. 聚合函数:将一列数据作为一个整体,进行纵向的计算。
	1. count:计算个数
		1. 一般选择非空的列:主键
		2. count(*)
	2. max:计算最大值
	3. min:计算最小值
	4. sum:计算和
	5. avg:计算平均值
	注意:聚合函数的计算,排除null值。
		解决方案:
			1. 选择不包含非空的列进行计算
			2. IFNULL函数
3. 分组查询:
	1. 语法:group by 分组字段;
	2. 注意:
		1. 分组之后查询的字段:分组字段、聚合函数
		2. where 和 having 的区别?
			1. where 在分组之前进行限定,如果不满足条件,则不参与分组。
			    having在分组之后进行限定,如果不满足结果,则不会被查询出来
			2. where 后不可以跟聚合函数,having可以进行聚合函数的判断。
		-- 按照性别分组。分别查询男、女同学的平均分
		SELECT sex , AVG(math) FROM student GROUP BY sex;
		-- 按照性别分组。分别查询男、女同学的平均分,人数
		SELECT sex , AVG(math),COUNT(id) FROM student GROUP BY sex;
		--  按照性别分组。分别查询男、女同学的平均分,人数 要求:分数低于70分的人,不参与分组
		SELECT sex , AVG(math),COUNT(id) FROM student WHERE math > 70 GROUP BY sex;
		--  按照性别分组。分别查询男、女同学的平均分,人数 要求:分数低于70分的人,不参与分组,分组之后。人数要大于2个人
		SELECT sex , AVG(math),COUNT(id) FROM student WHERE math > 70 GROUP BY sex HAVING COUNT(id) > 2;
		SELECT sex , AVG(math),COUNT(id) 人数 FROM student WHERE math > 70 GROUP BY sex HAVING 人数 > 2;
4. 分页查询
	1. 语法:limit 开始的索引,每页查询的条数;
	2. 公式:开始的索引 = (当前的页码 - 1* 每页显示的条数
		-- 每页显示3条记录 
		SELECT * FROM student LIMIT 0,3; --1页
		SELECT * FROM student LIMIT 3,3; --2页
		SELECT * FROM student LIMIT 6,3; --33. limit 是一个MySQL"方言"

DQL:多表查询

查询语法:
	select
		列名列表
	from
		表名列表
	where....
准备sql
	# 创建部门表
	CREATE TABLE dept(
		id INT PRIMARY KEY AUTO_INCREMENT,
		NAME VARCHAR(20)
	);
	INSERT INTO dept (NAME) VALUES ('开发部'),('市场部'),('财务部');
	# 创建员工表
	CREATE TABLE emp (
		id INT PRIMARY KEY AUTO_INCREMENT,
		NAME VARCHAR(10),
		gender CHAR(1), -- 性别
		salary DOUBLE, -- 工资
		join_date DATE, -- 入职日期
		dept_id INT,
		FOREIGN KEY (dept_id) REFERENCES dept(id) -- 外键,关联部门表(部门表的主键)
	);
	INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('孙悟空','男',7200,'2013-02-24',1);
	INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('猪八戒','男',3600,'2010-12-02',2);
	INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('唐僧','男',9000,'2008-08-08',2);
	INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('白骨精','女',5000,'2015-10-07',3);
	INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('蜘蛛精','女',4500,'2011-03-14',1);
	
笛卡尔积:
	有两个集合A,B .取这两个集合的所有组成情况。
	要完成多表查询,需要消除无用的数据
	
多表查询的分类:
	1. 内连接查询:
		1. 隐式内连接:使用where条件消除无用数据
			例子:
			-- 查询所有员工信息和对应的部门信息
			SELECT * FROM emp,dept WHERE emp.`dept_id` = dept.`id`;
			-- 查询员工表的名称,性别。部门表的名称
			SELECT emp.name,emp.gender,dept.name FROM emp,dept WHERE emp.`dept_id` = dept.`id`;
			SELECT 
				t1.name, -- 员工表的姓名
				t1.gender,-- 员工表的性别
				t2.name -- 部门表的名称
			FROM
				emp t1,
				dept t2
			WHERE 
				t1.`dept_id` = t2.`id`;
		2. 显式内连接:
			语法: select 字段列表 from 表名1 [inner] join 表名2 on 条件
			例如:
				SELECT * FROM emp INNER JOIN dept ON emp.`dept_id` = dept.`id`;	
				SELECT * FROM emp JOIN dept ON emp.`dept_id` = dept.`id`;	
		3. 内连接查询:
			1. 从哪些表中查询数据
			2. 条件是什么
			3. 查询哪些字段
	2. 外链接查询:
		1. 左外连接:
			语法:select 字段列表 from 表1 left [outer] join 表2 on 条件;
			查询的是左表所有数据以及其交集部分。
			例子:
				-- 查询所有员工信息,如果员工有部门,则查询部门名称,没有部门,则不显示部门名称
				SELECT 	t1.*,t2.`name` FROM emp t1 LEFT JOIN dept t2 ON t1.`dept_id` = t2.`id`;
		2. 右外连接:
			语法:select 字段列表 from 表1 right [outer] join 表2 on 条件;
			查询的是右表所有数据以及其交集部分。
			例子:
				SELECT 	* FROM dept t2 RIGHT JOIN emp t1 ON t1.`dept_id` = t2.`id`;
	3. 子查询:
		概念:查询中嵌套查询,称嵌套查询为子查询。
			-- 查询工资最高的员工信息
			-- 1 查询最高的工资是多少 9000
			SELECT MAX(salary) FROM emp;
			-- 2 查询员工信息,并且工资等于9000的
			SELECT * FROM emp WHERE emp.`salary` = 9000;
			-- 一条sql就完成这个操作。子查询
			SELECT * FROM emp WHERE emp.`salary` = (SELECT MAX(salary) FROM emp);
		子查询不同情况
			1. 子查询的结果是单行单列的:
				子查询可以作为条件,使用运算符去判断。 运算符: > >= < <= =
				-- 查询员工工资小于平均工资的人
				SELECT * FROM emp WHERE emp.salary < (SELECT AVG(salary) FROM emp);
			2. 子查询的结果是多行单列的:
				子查询可以作为条件,使用运算符in来判断
				-- 查询'财务部''市场部'所有的员工信息
				SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部';
				SELECT * FROM emp WHERE dept_id = 3 OR dept_id = 2;
				-- 子查询
				SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部');
			3. 子查询的结果是多行多列的:
				子查询可以作为一张虚拟表参与查询
				-- 查询员工入职日期是2011-11-11日之后的员工信息和部门信息
				-- 子查询
				SELECT * FROM dept t1 ,(SELECT * FROM emp WHERE emp.`join_date` > '2011-11-11') t2
				WHERE t1.id = t2.dept_id;
				-- 普通内连接
				SELECT * FROM emp t1,dept t2 WHERE t1.`dept_id` = t2.`id` AND t1.`join_date` >  '2011-11-11'