【MySQL】简单明了:单表查询

终于来到令人激动、也是数据库最重要的一个点了:查询操作。前文曾说过,操作关系型数据库就是在操作表,那么查询操作也就是在表格中查询指定数据的操作了。本文将教你在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 [选项]

 

查询指定字段信息:select 字段1,字段2,...from 表名;

 

查询表中所有字段:select * from 表名;

 

注意:使用"*"在练习、学习过程中可以使用,在实际开发中,不推荐使用。原因,要查询的字段信息不明确,若字段数量很多,会导致查询速度很慢。

 

distinct用于去除重复记录:select distinct 字段 from 表名;

 

表别名格式:

 

  • select * from 表名 as 别名;
  • select * from 表名 别名; --as关键词可以省略

 

列别名格式:

 

  • select 字段名 as 别名 from 表名;
  • select 字段名 别名 from 表名;

 

去重复的结果集:

 

SELECT DISTINCT * FROM 表名;

第一个SQL查询:

 

 

聚合函数

 

背景:

 

  • 之前我们所做的都是横向查询,它们都是根据条件一行一行地进行判断。
  • 如何实现纵向查询,即对一个列的所有数值进行某种运算。聚合函数。
  • 即,将一列数据作为一个整体,进行纵向计算。

 

聚合函数:使用方式是:作用在列名上。

 

count:统计指定列部位null的记录个数;

 

语法示例:SELECT COUNT(*) FROM 表名

 

注意:count聚合函数的计算,排除值为null的那一格;

 

  1. 即使是null,也加入计算:SELECT COUNT(*) FROM 表名; 或者 SELECT COUNT(主键) FROM 表名;
  2. 使用ifnull函数:SELECT COUNT(IFNULL(列名,0) FROM 表名;  (注释:把值为NULL的所在单元格看成是0)

 

 

  • 其他聚合函数:
  • sum:计算指定列的数值和,如果指定列的数据类型不是数值类型,那么计算结果为0;
  • 语法示例:SELECT SUM(列名) FROM 表名
  • max:计算指定列的最大值,如果该列是字符串类型,那么使用字符串排序运算;
  • min:计算指定列的最小值,如果该列是字符串类型,那么使用字符串排序运算;
  • avg:计算列的平均值,如果该列的数据类型不是数值类型,那么计算结果为0;SELECT AVG(DISTINCT p_price) AS avg_price from products;

获取某列的总和:SELECT sum(列名) FROM 表名;

获取某列的平均值:SELECT avg(列名) from 表名;

 

字段连接

 

有时,我们需要根据请求,对数据库中的不同列,进行数据计算字段(数据组合、格式控制),再返回。

 

理解计算字段中的拼接字符串concat()

 

SELECT CONCAT(pid,pname,page) AS 拼接:ID姓名年龄 FROM person;

执行结果:

 

CONCAT如何使用

语法:

  1. 要连接成一串的,全部在CONCAT()的括号内;
  2. 各个字段(列名)之间使用英文状态下的逗号分隔;
  3. 字符要用引号隔离,和使用英文逗号分隔;

示例:

SELECT CONCAT(pname,'(',page,psex,ptel,pemail,')') AS 个人信息 FROM person;

 

执行算术运算

 

SELECT pid,pname,page+5 AS new_age FROM person WHERE psex='woman';

 

文本处理函数

数值处理函数


WHERE 条件查询

格式:select 字段  from 表名  where 条件;

 

while条件的种类如下:

比较运算符

>  <  <=   >=   =  <>

大于、小于、大于(小于)等于、不等于(或者!=)

BETWEEN  ...AND...

显示在某一区间的值(含头含尾)

IN(参数为一个set集合)

显示在in列表中的值,例:in(100,200)

显示不在in列表中的值,例:not in(10,20)

LIKE 通配符

模糊查询,Like语句中有两个通配符

  1. % 用来匹配多个字符;例first_name like ‘a%’;%不能用于匹配NULL值!
  2. _ 用来匹配一个字符。例first_name like ‘a_’;

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 通配符:

  1. % 用来匹配多个字符;例first_name like ‘a%’;%不能用于匹配NULL值!
  2. _ 用来匹配一个字符。例first_name like ‘a_’;

 

REGEXP正则表达式:

检索pname中包含文本ject的所有行:SELECT pname FROM person WHERE pname REGEXP 'ject';

特性:

  1. 不区分大小写;
  2. “.”:匹配任意字符;
  3. “\\-”:匹配“-”,“\\.”:匹配“.”;

辨析LIKE和REGEXP:

SELECT pname FROM person WHERE pname LIKE 'ject';  -- 不会显示pname为ject的所在行;
SELECT pname FROM person WHERE pname REGEXP 'ject';  -- 会显示pname为ject的所在行;

  1. LIKE匹配的是整个列。如果被匹配的文本在列值中出现,LIKE将不会找到它,相应的行也不会被返回。
  2. REGEXP是在列中的值进行匹配。如果被匹配的文本在列值中出现,REGEXP将会找到它,并将它返回。

GROUP BY 分组查询

功能:把同一列中的重复内容项合并成一个项,并操作处理这些重复内容项的各个数值。

 

使用格式:GROUP BY 被分组的列名

  1. 可以跟着聚合函数
  2. 被分组的列,要出现在SELECT选择列的后面
  3. GROUP BY子句必须出现在where子句之后,ORDER BY 子句之前
  4. 如果分组列中具有NULL值,则NULL将作为一个分组返回。如果列中有多个NULL值,则将它们作为一组

 

核心特性:

  1. where是用来过滤记录的,HAVING是用来过滤分组的,HAVING具备where的所有语法。
  2. 过滤的时机不相同:先过滤Where后过滤Having
  3. WHERE是在查询表时逐行过滤以选取满足条件的记录,having是在数据查询后并且分完组后对分组进行过滤的
  4. HAVING必须跟在group BY之后
  5. 查询语句执行顺序:5select 1from 2where 3group by 4having 6order 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;

 

ORDER BY 排序查询

功能:选取某一行对数据进行排序。

语法格式:在普通查询语句后接“SELECT * FROM person ORDER BY 列名 [DESC|ASC]”

  • DESC:降序排列
  • ASC:升序,可以不写(默认)

如果列名1相同的情况下,按照列名2继续排序:

SELECT * FROM 表名 ORDER BY 列名1 [DESC|ASC], 列名2 [DESC|ASC];

 

按年龄进行排序:


LIMIT 分页操作

理解:对于一个查询,其结果有很多。一个页面可能太长了,显示不下,所以我们需要对其进行分页,分成不长的几页。

 

分页操作的语法:

SELECT * FROM 表名 LIMIT 开始索引,每页显示的条目数;

开始索引 = (当前的页码 - 1)x 每页显示的条数

 

每页显示3条记录:

SELECT * FROM 表名 LIMIT 0,3;(第一页:从0开始查,只显示前3条记录)

SELECT * FROM 表名 LIMIT 3,3;(第二页:从3开始查,只显示前3条记录)

 

从查询结果的第2项开始,输出两项:


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章