终于来到令人激动、也是数据库最重要的一个点了:查询操作。前文曾说过,操作关系型数据库就是在操作表,那么查询操作也就是在表格中查询指定数据的操作了。本文将教你在MySQL中基础的单表查询语法,十分清晰明了,一看一练包会!(注:推荐读物《MySQL必知必会 人民邮电出版社》)
Table of Contents
创建一个练习用的数据库和表
SELECT [选项]
聚合函数
字段连接
执行算术运算
文本处理函数
数值处理函数
WHERE 条件查询
正则表达式查询
GROUP BY 分组查询
ORDER BY 排序查询
LIMIT 分页操作
本文将围绕以下的查询语法展开,由浅入深,帮助你快速建立查询操作体系结构(奥利给):
SELECT [选项] 字段列表 FROM 数据源 WHERE条件
GROUP BY分组 HAVING条件
ORDER BY排序
LIMIT限制;
PS:建议先看我的前两篇文章,教你如何创建MySQL数据库和表~~
【MySQL】如何管理数据库:https://blog.hackyle.net/index.php/database/mysql-manage-database/
【MySQL】如何管理表:https://blog.hackyle.net/index.php/database/mysql-manage-table/
打开SQLyog:
-- 1.创建一个名为kdb的数据库并设置编码
CREATE DATABASE kdb CHARACTER SET utf8;
-- 2.切换到kdb数据库
USE kdb;
-- 3.创建一个表格
CREATE TABLE person (
pid INT PRIMARY KEY AUTO_INCREMENT COMMENT '人的编号,作为主键,编号自动增长',
pname VARCHAR(20) NOT NULL COMMENT '人的姓名,不可以为空',
page INT DEFAULT NULL COMMENT '年龄,默认为空',
paddress VARCHAR(50) DEFAULT NULL COMMENT '住址,默认为空',
ptel VARCHAR(15) DEFAULT NULL COMMENT '电话',
pemail VARCHAR(50) DEFAULT NULL COMMENT '电邮'
);
执行完上述SQL语句后:
添加一些记录:
-- 4.添加几条记录
INSERT INTO person VALUES (1,'Jhon',20,'HongKong','16818181818','[email protected]'),
(2,'Project Alice',32,'raccoon city','15745452525','[email protected]'),
(3,'Fukada Eimi',28,'Japanese','10100101010','[email protected]'),
(4,'Yourer',25,'Japanese','19191918989','[email protected]'),
(5,'anay',22,'Taiwan','11100101001','[email protected]*on')
现在可以愉快地玩耍了~~~
查询指定字段信息:select 字段1,字段2,...from 表名;
查询表中所有字段:select * from 表名;
注意:使用"*"在练习、学习过程中可以使用,在实际开发中,不推荐使用。原因,要查询的字段信息不明确,若字段数量很多,会导致查询速度很慢。
distinct用于去除重复记录:select distinct 字段 from 表名;
表别名格式:
列别名格式:
去重复的结果集:
SELECT DISTINCT * FROM 表名;
第一个SQL查询:
背景:
聚合函数:使用方式是:作用在列名上。
count:统计指定列部位null的记录个数;
语法示例:SELECT COUNT(*) FROM 表名
注意:count聚合函数的计算,排除值为null的那一格;
获取某列的总和:SELECT sum(列名) FROM 表名;
获取某列的平均值:SELECT avg(列名) from 表名;
有时,我们需要根据请求,对数据库中的不同列,进行数据计算字段(数据组合、格式控制),再返回。
理解计算字段中的拼接字符串concat()
SELECT CONCAT(pid,pname,page) AS 拼接:ID姓名年龄 FROM person;
执行结果:
CONCAT如何使用
语法:
示例:
SELECT CONCAT(pname,'(',page,psex,ptel,pemail,')') AS 个人信息 FROM person;
SELECT pid,pname,page+5 AS new_age FROM person WHERE psex='woman';
格式:select 字段 from 表名 where 条件;
while条件的种类如下:
比较运算符 |
> < <= >= = <> |
大于、小于、大于(小于)等于、不等于(或者!=) |
BETWEEN ...AND... |
显示在某一区间的值(含头含尾) |
|
IN(参数为一个set集合) |
显示在in列表中的值,例:in(100,200) 显示不在in列表中的值,例:not in(10,20) |
|
LIKE 通配符 |
模糊查询,Like语句中有两个通配符:
|
|
IS NULL |
判断是否为空 is null; 判断为空 is not null; 判断不为空 |
|
逻辑运算符 |
AND |
多个条件同时成立 |
OR |
多个条件任一成立 |
|
NOT |
不成立,例:where not(salary>100); |
由于本个表没有相关测试数据(懒得写),这里就直接脑补一波:
示例:
价格小于10:
SELECT p_name,p_price FROM products WHERE p_price<10;
价格不等于10:
SELECT p_name,p_price FROM products WHERE p_price!=10;等价于
SELECT p_name,p_price FROM products WHERE p_price<>10;
价格在10到100之间:
SELECT p_name,p_price FROM products WHERE p_price BETWEEN 10 AND 100;
检查有无空值:
SELECT p_name FROM products WHERE p_price IS NULL;
OR操作符的使用:
SELECT p_name,p_price FROM products WHERE p_id=100 OR p_id=200;
OR、AND操作符的联合使用:
SELECT p_name,p_price FROM products WHERE p_id=100 OR p_id=200 AND p_price>=10;
上面语句执行后并未按照预期进行过滤。原因是,在处理OR之前,优先处理AND;由于AND在计算次序中优先级更高,操作符被错误地组合了。
SELECT p_name,p_price FROM products WHERE (p_id=100 OR p_id=200) AND p_price>=10;
LIKE 通配符:
REGEXP正则表达式:
检索pname中包含文本ject的所有行:SELECT pname FROM person WHERE pname REGEXP 'ject';
特性:
辨析LIKE和REGEXP:
SELECT pname FROM person WHERE pname LIKE 'ject'; -- 不会显示pname为ject的所在行;
SELECT pname FROM person WHERE pname REGEXP 'ject'; -- 会显示pname为ject的所在行;
功能:把同一列中的重复内容项合并成一个项,并操作处理这些重复内容项的各个数值。
使用格式:GROUP BY 被分组的列名
核心特性:
添加一个字段,方便分组查询:
ALTER TABLE person ADD psex VARCHAR(10) DEFAULT 'man' COMMENT '性别';
UPDATE person SET psex='woman' WHERE pid BETWEEN 2 AND 3;
先看看表中的数据是什么样的:
统计一下person表中的男人和女人各有多少人:
统计一下person表中的各地区人的数量:
以下是一些分组查询的示例(没有实际案例,如果看不懂,跳过即可):
理解分组查询:
1. 根据“列名1”字段分组,分组后统计商品的个数:
SELECT 列名1,count(*) from 表名 GROUP BY 列名1;
2. 根据“列名1”分组,分组统计“列名2”的平均价格,并且平均价格大于20000元:
SELECT 列名1,avg(列名2) FROM 表名 GROUP BY 列名1 having avg(“列名2”)>20000;
GROUP BY(分组查询)的示例:
1) 查询每个部门的平均工资:
SELECT deptno AS 部门,AVG(sal) AS 平均工资 FROM emp GROUP BY deptno;
2) 查询每个职位的最高、最低工资:
SELECT job AS 职位, MAX(sal) AS 最高工资, MIN(sal) AS 最低工资 FROM emp GROUP BY job;
3) 查询每个部门的每个职位的最高工资:
SELECT DISTINCT deptno AS 部门, job AS 职位, MAX(sal) 最高工资 FROM emp GROUP BY job;
4) 查询每个部门的平均工资:
SELECT deptno AS 部门, AVG(sal) AS 平均工资 FROM emp GROUP BY deptno;
功能:选取某一行对数据进行排序。
语法格式:在普通查询语句后接“SELECT * FROM person ORDER BY 列名 [DESC|ASC]”
如果列名1相同的情况下,按照列名2继续排序:
SELECT * FROM 表名 ORDER BY 列名1 [DESC|ASC], 列名2 [DESC|ASC];
按年龄进行排序:
理解:对于一个查询,其结果有很多。一个页面可能太长了,显示不下,所以我们需要对其进行分页,分成不长的几页。
分页操作的语法:
SELECT * FROM 表名 LIMIT 开始索引,每页显示的条目数;
开始索引 = (当前的页码 - 1)x 每页显示的条数
每页显示3条记录:
SELECT * FROM 表名 LIMIT 0,3;(第一页:从0开始查,只显示前3条记录)
SELECT * FROM 表名 LIMIT 3,3;(第二页:从3开始查,只显示前3条记录)
从查询结果的第2项开始,输出两项: