SQL语句的学习

首先我们先来了解一下什么是SQL语句,它有什么作用,又分别有哪些?
  SQL语句的概念:结构化查询语言(Structured Query Language)简称SQL,SQL语句就是对数据库进行操作的一种语言。
  SQL作用:通过SQL语句我们可以方便的操作数据库中的数据、表、数据库。 SQL是数据库管理系统都需要遵循的规范。不同的数据库生产厂商都支持SQL语句,但都有特有内容。
  SQL语句分类:
    1. DDL(Data Defifinition Language)数据定义语言 用来定义数据库对象:数据库,表,列等。关键字:create,drop,alter等
    2. DML(Data Manipulation Language)数据操作语言 用来对数据库中表的数据进行增删改。关键字:insert,delete, update等
    3. DCL(Data Control Language)数据控制语言(了解)用来定义数据库的访问权限和安全级别,及创建用户。关键字:GRANT, REVOKE等
    4. TCL(Transaction Control Language) 事务控制语言用于控制数据库的事务操作,关键字; COMMIT,SAVEPOINT,ROLLBACK等
    5. DQL(Data Query Language) 数据查询语言
 
DQL语言并不是属于MYSQL官方的分类,但是对数据库的操作最多就是查询,所以我们的程序员把查询语句的语句称作为DQL语言,学习最快的方法莫过于一边学一边练:

数据准备

CREATE TABLE student4 ( id INT, NAME VARCHAR(20), age INT, sex VARCHAR(5), address VARCHAR(100), math INT, english INT );
INSERT INTO student4(id,NAME,age,sex,address,math,english) VALUES 
(1,‘马云‘,55,‘男‘,‘杭 州‘,66,78),
(2,‘马化腾‘,45,‘女‘,‘深圳‘,98,87),
(3,‘马景涛‘,55,‘男‘,‘香港‘,56,77),
(4,‘柳 岩‘,20,‘女‘,‘湖南‘,76,65),
(5,‘柳青‘,20,‘男‘,‘湖南‘,86,NULL),
(6,‘刘德华‘,57,‘男‘,‘香港‘,99,99), 
(7,‘马德‘,22,‘女‘,‘香港‘,99,99),
(8,‘德玛西亚‘,18,‘男‘,‘南京‘,56,65);INSERT INTO student4(id,NAME,age,sex,address,math,english) VALUES (9,‘唐僧‘,25,‘男‘,‘长安‘,87,78), (10,‘孙悟空‘,18,‘男‘,‘花果山‘,100,66), (11,‘猪八戒‘,22,‘男‘,‘高老庄‘,58,78), (12,‘沙僧‘,50,‘男‘,‘流沙河‘,77,88), (13,‘白骨精‘,22,‘女‘,‘白虎岭‘,66,66), (14,‘蜘蛛精‘,23,‘女‘,‘盘丝洞‘,88,88);

SQL语句书写格式及顺序:我们暂时不用理它,学完再回头看看即可

SELECT *|字段列表 [as 别名] FROM 表名 [WHERE子句] [GROUP BY子句][HAVING子句][ORDER BY子句][LIMIT子句];

1、DISTINCT 关键字作用 ===》清除重复值

SELECT DISTINCT 字段名1,字段名2 ... FROM 表名;  //注意查询多个字段必须是相同重复,否则会失败//案例:查询所有name的唯一值SELECT DISTINCT NAME FROM student4

2、IN 以及 NOT IN 关键字作用 ===》多值条件查询

//SELECT 字段名 FROM 表名 WHERE 字段 in (数据1, 数据2...); 
//IN 里面的每个数据都会作为一次条件,只要满足条件的就会显示
// 案例:查询出ID为 1,3,5 的所有用户
SELECT * FROM student4 WHERE id IN(1,3,5)
//案例:查询出所有ID不等于 1,3,5 的所有用户
SELECT* FROM student4 WHERE id NOT IN(1,3,5)

3、 BETWEEN 关键字作用 ===》 范围查询

//SELECT * FROM 表名 WHERE 字段 BETWEEN 值1 AND 值2
//案例:查询math成绩大于等于60,且小于等于90的学生
SELECT * FROM student4 WHERE math BETWEEN 60 AND 98

4、LIKE 关键字作用 ===》模糊查询

//SELECT * FROM 表名 WHERE 字段名 LIKE ‘通配符字符串‘; MySQL通配符有两个: % : 表示0个或多个字符(任意个字符) _ : 表示一个字符
//案例1:查询姓马的学生
SELECT * FROM student4 WHERE NAME LIKE ‘马%‘
//案例2:查询姓名中包含‘德‘字的学生
SELECT * FROM student4 WHERE NAME LIKE ‘%德%‘
//案例3:查询姓马,且姓名有三个字的学生 这里需要两个下划线
SELECT * FROM student4 WHERE NAME LIKE ‘马__‘

5、ORDER BY 关键字作用 ===》 排序查询 排序又有单列排序以及组合排序 ASC:升序,DESC:降序

//SELECT 字段名 FROM 表名 WHERE 字段=值 ORDER BY 字段名 [ASC|DESC];
//案例:查询所有数据,使用年龄降序排序 ===> 单列排序
SELECT * FROM student4 ORDER BY age DESC
// 案例:查询所有数据,在年龄降序排序的基础上,如果年龄相同再以数学成绩降序排序 ==》 组合排序
SELECT * FROM student4 ORDER BY age DESC, math DESC

6、聚合函数 == > SELECT COUNT(age) FROM 表名;

// 注意在使用聚合函数查询数据时某个字段数据可能为空,由于记录为NULL的字段不统计 所有我们要添加 IFNULL关键字
//IFNULL(expr1, expr2)的用法:假如expr1 不为 NULL,则 IFNULL() 的返回值为 expr1; 否则其返回值为expr2
// count : 统计指定列记录数,记录为NULL的不统计
SELECT COUNT(IFNULL(NAME,0)) FROM student4;
//SUM : 计算指定列的数值和,如果不是数值类型,那么计算结果为0 
SELECT SUM(IFNULL(math,0)) FROM student4;
// MAX : 计算指定列的最大值 
SELECT MAX(IFNULL(math,0)) FROM student4;
// Min : 计算指定列的最小值
SELECT MIN(IFNULL(math,0)) FROM student4;
// AVG : 计算指定列的平均值,如果不是数值类型,那么计算结果为0
SELECT AVG(IFNULL(math,0)) FROM student4;

7、GROUP BY 关键字作用 ===》 分组查询 将字段结果相同的数据作为一组

//SELECT 字段1,字段2... FROM 表名 GROUP BY 分组字段 [HAVING 条件];
//分组通常是和聚合函数一起使用
// 案例:按性别分组,查询男女各多少人
SELECT sex,COUNT(sex) FROM student4 GROUP BY sex 
//案例:查询年龄大于25岁的人,按性别分组,统计每组的人数,并只显示性别人数大于2的数据
SELECT sex, COUNT(sex) FROM student4 WHERE age>25 GROUP BY sex HAVING COUNT(sex)>2
// 注意:HAVING关键字与WHERE 关键字的区别:HAVING 是在分组后对条件进行过滤,可以使用聚合函数,WHERE 是在分组前对条件进行过滤,不可以使用聚合函数

8、LIMIT 关键字作用 ===> 限制查询记录条数,相当于分页 offset:起始 默认0开始, length:显示条数 

//SELECT 字段1,字段2... FROM 表名 GROUP BY 分组字段 [HAVING 条件] LIMIT offset,length
// 案例:查询学生表中数据,从第三条开始显示,显示6条 
SELECT * FROM student4 LIMIT 2,6 -- 注意默认从0 开始

9、表与表之间的关系:一对一、一对多、多对多

10、数据的多表查询: 数据查询需要关联到多张表

11、连接查询

1、内连接:用左边表的记录去匹配右边表的记录,如果符合条件的则显示
1.1、隐式内连接:看不到 JOIN 关键字,条件使用 WHERE 指定//SELECT * FROM 表1, 表2... WHERE 关联条件//案例1:查询每个部门有哪些人SELECT * FROM dept d, emp e WHERE d.id=e.dept_id
1.2、显示内连接:使用 INNER JOIN ... ON 语句, 
//INNER SELECT 字段名 FROM 左表 INNER JOIN 右表 ON 条 件;
// 案例2:查询唐僧的信息,显示员工id,姓名,性别,工资和所在的部门名称
SELECT e.id, e.name,e.gender,e.salary,d.name FROM dept d INNER JOIN emp e ON d.id = e.dept_id
2、外连接:在内连接的基础上保证左表或右表的数据全部显示2.1、左外连接:使用 LEFT OUTER JOIN ... ON , 用左边表的记录去匹配右边表的记录,如果符合条件的则显示;否则,显示NULL
//SELECT 字段名 FROM 左表 LEFT OUTER JOIN 右表 ON 条件 
SELECT * FROM dept d LEFT OUTER JOIN emp e ON d.id=e.dept_id
// OUTER 可以省略
SELECT * FROM dept d LEFT JOIN emp e ON d.id = e.dept_id

2.2、右外连接:使用 RIGHT OUTER JOIN ... ON , OUTER 可以省略 用右边表的记录去匹配左边表的记录,如果符合条件的则显示;否则,显示NULL
//SELECT 字段名 FROM 左表 RIGHT OUTER JOIN 右表 ON 条件;
SELECT * FROM dept d RIGHT JOIN emp e ON d.id=e.dept_id

总结:

1、内连接查询步骤:1. 确定查询哪些表;2. 确定表连接条件;3. 确定查询字段;

2、多表查询格式如下:

SELECT * FROM 表1 INNER JOIN 表2 INNER JOIN 表3 ... ON 关联条件1 AND 关联条件2 ...

12、子查询:一条SELECT语句结果作为另一条SELECT语法一部分(查询条件,查询结果,表)

-- 子查询的结果有多种情况:单列单值、单列多行、多列多行
-- 当子查询结果只要是 单列单值 的时候 ,肯定在 WHERE 后面作为 条件 
-- SELECT 查询字段 FROM 表 WHERE 字段=(子查询);
-- 案例: 查询工资最高的员工是谁 ==> 分析:首先查询工资的最大值,然后再根据这个值去查询员工信息
SELECT * FROM emp e WHERE salary = (SELECT MAX(salary) FROM emp)

-- 当子查询结果为 单列多行 的时候,同样在 WHERE 后面作为 条件 ,其结果集类似于一个数组,父查询使用 IN 运算符 
-- SELECT 查询字段 FROM 表 WHERE 字段 IN (子查询);
-- 案例:查询工资大于5000的员工,来自于哪些部门的名字 == 》 分析:首先查找出工资大于5000的员工id,再根据id查询相应员工所在的部门
SELECT * FROM dept WHERE dept.id IN (SELECT dept_id FROM emp WHERE salary > 5000)

-- 当子查询结果为 多行多列 的时候,肯定在 FROM 后面作为 表 
-- SELECT 查询字段 FROM (子查询) 表别名 WHERE 条件; 子查询作为表需要取别名,否则这张表没用名称无法访问表中的字段
-- 案例:查询出2011年以后入职的员工信息,包括部门名称
SELECT * FROM (SELECT * FROM emp WHERE join_date > ‘2011-01-01‘) st LEFT JOIN dept d ON st.dept_id = d.id

子查询总结:

1、子查询结果只要是 单列 ,肯定在 WHERE 后面作为 条件 ====》 SELECT 查询字段 FROM 表 WHERE 字段=(子查询);
2、子查询结果只要是 多列 ,肯定在 FROM 后面作为 表    ====》 SELECT 查询字段 FROM (子查询) 表别名 WHERE 条件;