1. 基础查询
概念: 数据查询语言(DQL),负责查询数据,所有SELECT开头的语句全属于DQL的范围之内。
- 基本格式:
SELECT 字段,字段... FROM 查询范围: - 注释使用
--加一个空格。- mysql中可以使用
#作为注释。
- mysql中可以使用
- 查询全部用
*替代,但是不建议使用,查询效率低。- mysql中的
*可以直接和其他字段一起展示,但并不建议。
- mysql中的
- 代码语法不区分大小写,建议写成全大写有助于提高效率。
- 对于mysql来说,表中的值也不区分大小写。
- 字段可以起别名,用
AS关键字来标注,也可以省略不写,别名可以使用中文但不建议。 - 表名可以起别名,不建议使用
AS标注,对表起别名可以提高查询效率。 - 字符类型数据用单引号或双引号标注,建议使用单引号。
- 数字类型数据可以直接进行计算,null值和任何值进行计算结果都为null。
源码: dql/基础查询.sql
SELECT *
FROM EMP;
SELECT ENAME, JOB
FROM EMP;
SELECT ENAME AS EMP_NAME, JOB EMP_JOB
FROM EMP;
SELECT ENAME "EMP_NAME", JOB 'EMP_JOB'
FROM EMP;
SELECT T.ENAME, T.SAL, SAL + 200 TOTAL
FROM EMP T;
SELECT T.ENAME, T.COMM, COMM + 200 TOTAL
FROM EMP T;
2. 查询排序
概念: ORDER BY 关键字可以对结果集进行排序:
- 格式:
ORDER BY 排序字段, 排序字段... 排序规则ASC代表升序,默认值,可以省略不写。DESC代表降序。
ORDER BY是对结果集的排序,所以必须要写在语句最后,也是程序最后一步运行的。ORDER BY不参与任何计算,也不会改变任何一个值。ORDER BY后可以使用多个字段,按顺序进行分组,用逗号隔开。
源码: dql/查询排序.sql
SELECT JOB, SAL
FROM EMP
ORDER BY SAL;
SELECT JOB, SAL
FROM EMP
ORDER BY SAL DESC;
SELECT SAL, EMPNO
FROM EMP
ORDER BY SAL, EMPNO DESC;
3. 条件查询
概念: WHERE 关键字可以在查询的过程中,逐条进行条件判断:
- 格式:
SELECT * FROM 表名 WHERE 条件:- 即使多个条件,
WHERE关键字也只能有一个。 - 条件允许使用
AND,OR,NOT,<>,!=来做逻辑判断。 AND的优先级高于OR。
- 即使多个条件,
- 为了提高效率,筛选过程慢,即筛选量大的条件,要尽量往后放。
源码: dql/条件查询.sql
SELECT *
FROM EMP
WHERE ENAME = 'SMITH';
SELECT ENAME
FROM EMP
WHERE ENAME != 'SMITH';
SELECT ENAME
FROM EMP
WHERE ENAME <> 'SMITH';
SELECT ENAME, SAL
FROM EMP
WHERE SAL + 500 > 2000;
SELECT ENAME, SAL
FROM EMP
WHERE SAL > 2000
AND SAL <= 3000;
SELECT ENAME, SAL, JOB
FROM EMP
WHERE SAL = 1250
OR JOB = 'SALESMAN';
4. 模糊查询
概念: LIKE 关键字可以在查询的过程中,逐条进行模糊匹配:
- 占位符:
%表示随意个数占位,_表示只占一位。 - 可以使用
LIKE ESCAPE 转义字符来指定转义字符,符号建议使用\。- mysql可以直接使用
\作为转义字符而不需要使用ESCAPE声明。
- mysql可以直接使用
- 两个单引号可以表示一个单引号:
- mysql的
\可以直接作用于单引号上。
- mysql的
- 模糊查询的内容不区分大小写。
脚本: 插入 %张% 和 '李' 为了测试。
INSERT INTO EMP (EMPNO, ENAME)
VALUES (1111, '%张%'),
(2222, '\'李\'');
COMMIT;
源码: dql/模糊查询.sql
SELECT ENAME
FROM EMP
WHERE ENAME LIKE 'S%';
SELECT ENAME
FROM EMP
WHERE ENAME LIKE '_M%';
SELECT *
FROM EMP
WHERE ENAME LIKE '%''%';
INSERT INTO EMP (EMPNO, ENAME)
VALUES (1111, '%张%'),
(2222, '\'李\'');
COMMIT;
SELECT ENAME
FROM EMP
WHERE ENAME LIKE '%\%%';
SELECT ENAME
FROM EMP
WHERE ENAME LIKE '%$%%' ESCAPE '$';
SELECT ENAME
FROM EMP
WHERE ENAME LIKE '%\'%';
SELECT ENAME
FROM EMP
WHERE ENAME LIKE '%''%';
5. 分组查询
概念: GROUP BY 关键字可以进行分组,分组查询最终只能得到一列数据。
- 分组查询
FROM前的字段只能是GROUP BY后出现的字段。- mysql中允许出现其他字段,但不建议。
- 分组查询不忽略null值,即null值也可以独立成为一组。
- 分组查询可以和
WHERE一起使用,会先执行WHERE,再进行GROUP BY。 GROUP BY后可以使用多个字段,按顺序进行分组,用逗号隔开。
源码: dql/分组查询.sql
SELECT JOB
FROM EMP
GROUP BY JOB;
SELECT JOB
FROM EMP
WHERE SAL > 2000
GROUP BY JOB;
SELECT JOB, ENAME
FROM EMP
GROUP BY JOB, ENAME;
6. 子查询
概念: 利用A查询提供一个临时的结果集供B使用,则可以称A为B的子查询:
- 单行子查询:子查询先独立执行且只执行一次,结果返回一行数据,供B使用。
- 多行子查询:子查询先独立执行且只执行一次,结果返回多行数据,供B使用。
ANY(子查询): 某些信息符合,结果集中是OR的关系,不等式专用。SOME(子查询): 某些信息符合,结果集中是OR的关系,等式专用。ALL(子查询): 全部信息符合,结果集中是AND的关系。
- 关联子查询:父查询每查询一条数据都需要先进行一次子查询,父子查询互相依靠,子查询无法独立运行。
- 子查询只要有返回值(不在乎返回值是什么),则父查询输出,否则跳过。
- 关联子查询的关键字是:
EXISTS(子查询)和NOT EXISTS(子查询)。
源码: dql/子查询.sql
SELECT ENAME, SAL
FROM EMP
WHERE SAL > (SELECT SAL FROM EMP WHERE ENAME = 'MARTIN');
SELECT ENAME, SAL
FROM EMP
WHERE SAL > ANY (SELECT SAL FROM EMP WHERE DEPTNO = 10);
SELECT ENAME, SAL
FROM EMP
WHERE SAL = SOME (SELECT SAL FROM EMP WHERE DEPTNO = 10);
SELECT ENAME, SAL
FROM EMP
WHERE SAL > ALL (SELECT SAL FROM EMP WHERE DEPTNO = 20);
SELECT DEPTNO, DNAME
FROM DEPT
WHERE EXISTS(SELECT 1 FROM EMP WHERE EMP.DEPTNO = DEPT.DEPTNO);
SELECT DEPTNO, DNAME
FROM DEPT
WHERE NOT EXISTS(SELECT 1 FROM EMP WHERE EMP.DEPTNO = DEPT.DEPTNO);
7. 分页查询
概念: LIMIT 关键字可以进行分页处理:
- 当数据量很大时,一次性查询结果就会变得很慢,为了提高查询效率,我们可以使用mysql的分页查询功能。
- 格式:
SELECT * FROM 表名 LIMIT N:从第头开始,显示N条。SELECT * FROM 表名 LIMIT M, N:从第M条开始(包括M),显示N条。
- 优化:如果M值过大,会导致分页效率低,因为mysql需要从0开始进行操作,建议先使用条件查询将数据进行限定,限定到M后再直接
LIMIT N进行分页,效率会大大提升。
源码: dql/分页查询.sql
SELECT *
FROM EMP
LIMIT 5;
SELECT *
FROM EMP
LIMIT 5, 5;
SELECT *
FROM EMP
LIMIT 100000, 100;
SELECT *
FROM EMP
WHERE EMPNO BETWEEN 1000000 AND 1000100
LIMIT 100;
8. 联表查询
概念: JOIN 关键字可以进行联表查询:
- 很多时候,我们需要的数据来自于多张表中,这时候我们就需要连表,两表成功相连需要一个联合条件。
- 格式:
- SQL92:
SELECT * FROM 表A, 表B WHERE 联合条件 - SQL99:
SELECT * FROM 表A JOIN 表B ON 联合条件
- SQL92:
- 内联:
INNER JOIN,仅仅显示满足连接条件的信息,INNER可省略。 - 左外联:
LEFT JOIN,完整显示左侧信息,即使不满足连接条件。 - 右外联:
RIGHT JOIN,完整显示右侧信息,即使不满足连接条件。 - 自联:将自己的表分成多个部分进行联合。
- 联表后如果出现相同列名,建议使用表名或表名的别名作为前缀,加以区分。
源码: dql/联表查询.sql
SELECT EMPNO, ENAME, E.DEPTNO, DNAME
FROM EMP E,
DEPT D
WHERE E.DEPTNO = D.DEPTNO;
SELECT EMPNO, ENAME, E.DEPTNO, DNAME
FROM EMP E
JOIN DEPT D ON E.DEPTNO = D.DEPTNO;
SELECT EMPNO, ENAME, E.DEPTNO, DNAME
FROM EMP E
INNER JOIN DEPT D ON E.DEPTNO = D.DEPTNO;
SELECT EMPNO, ENAME, E.DEPTNO, DNAME
FROM EMP E
LEFT JOIN DEPT D ON E.DEPTNO = D.DEPTNO;
SELECT EMPNO, ENAME, D.DEPTNO, DNAME
FROM EMP E
RIGHT JOIN DEPT D ON E.DEPTNO = D.DEPTNO;
SELECT XIAO.ENAME, DA.ENAME
FROM EMP XIAO
JOIN EMP DA ON DA.EMPNO = XIAO.MGR;
9. 集合查询
概念: UNION 关键字可以对两个结果集进行并集查询:
- 格式:
UNION:返回两个结果集的并集,并过滤相同信息。UNION ALL:返回两个结果集的并集,但不过滤相同信息。
- 参加运算的集合必须有相同的列,如果不相同用null补,而且列的类型必须对应。
- 并集运算中,null值不进行忽略。
源码: dql/集合查询.sql
(SELECT DEPTNO FROM DEPT)
UNION
(SELECT DEPTNO FROM EMP);
(SELECT DEPTNO FROM DEPT)
UNION ALL
(SELECT DEPTNO FROM EMP);
10. 正则查询
概念: REGEXP 关键字可以进行正则查询。
- 格式:
SELECT * FROM 表名 WHERE 字段 REGEXP '正则表达式模板'
正则表达式符号表
源码: dql/正则查询.sql
SELECT ENAME
FROM EMP
WHERE ENAME REGEXP '^S';
SELECT ENAME
FROM EMP
WHERE ENAME REGEXP 'H$';
SELECT ENAME
FROM EMP
WHERE ENAME REGEXP 'S';
SELECT ENAME
FROM EMP
WHERE ENAME REGEXP '^[AEIOU]|MS$';