GROUP BY 语句根据一个或多个列对结果集进行分组。
在分组的列上我们可以使用 COUNT
, SUM
, AVG
,等函数。
实例演示:
对于这样一个数据表
mysql> SELECT * FROM employee_tbl;
+----+--------+---------------------+--------+
| id | name | date | signin |
+----+--------+---------------------+--------+
| 1 | 小明 | 2016-04-22 15:25:33 | 1 |
| 2 | 小王 | 2016-04-20 15:25:47 | 3 |
| 3 | 小丽 | 2016-04-19 15:26:02 | 2 |
| 4 | 小王 | 2016-04-07 15:26:14 | 4 |
| 5 | 小明 | 2016-04-11 15:26:40 | 4 |
| 6 | 小明 | 2016-04-04 15:26:54 | 2 |
+----+--------+---------------------+--------+
6 rows in set (0.00 sec)
使用 GROUP BY 语句 将数据表按名字进行分组,并统计每个人有多少条记录:
mysql> SELECT name, COUNT(*) FROM employee_tbl GROUP BY name;
+--------+----------+
| name | COUNT(*) |
+--------+----------+
| 小丽 | 1 |
| 小明 | 3 |
| 小王 | 2 |
+--------+----------+
3 rows in set (0.01 sec)
WITH ROLLUP 可以实现在分组统计数据基础上再进行相同的统计(SUM,AVG,COUNT…)。
我们将以上的数据表按名字进行分组,再统计每个人登录的次数:
mysql> SELECT name, SUM(signin) as signin_count FROM employee_tbl GROUP BY name WITH ROLLUP;
+--------+--------------+
| name | signin_count |
+--------+--------------+
| 小丽 | 2 |
| 小明 | 7 |
| 小王 | 7 |
| NULL | 16 |
+--------+--------------+
4 rows in set (0.00 sec)
其中记录 NULL 表示所有人的登录次数。
我们可以使用 coalesce 来设置一个可以取代 NUll 的名称
mysql> SELECT coalesce(name, '总数'), SUM(signin) as signin_count FROM employee_tbl GROUP BY name WITH ROLLUP;
+--------------------------+--------------+
| coalesce(name, '总数') | signin_count |
+--------------------------+--------------+
| 小丽 | 2 |
| 小明 | 7 |
| 小王 | 7 |
| 总数 | 16 |
+--------------------------+--------------+
4 rows in set (0.01 sec)
在前几章节中,我们已经学会了如何在一张表中读取数据,这是相对简单的,但是在真正的应用中经常需要从多个数据表中读取数据。
本章节我们将向大家介绍如何使用 MySQL 的 JOIN
在两个或多个表中查询数据。
你可以在 SELECT, UPDATE 和 DELETE 语句中使用 Mysql 的 JOIN 来联合多表查询。
JOIN 按照功能大致分为如下三类:
INNER JOIN
(内连接,或等值连接):获取两个表中字段匹配关系的记录。LEFT JOIN
(左连接):获取左表所有记录,即使右表没有对应匹配的记录。RIGHT JOIN
(右连接): 与 LEFT JOIN 相反,用于获取右表所有记录,即使左表没有对应匹配的记录。我们在RUNOOB数据库中有两张表 tcount_tbl 和 runoob_tbl。两张数据表数据如下:
mysql> use RUNOOB;
Database changed
mysql> SELECT * FROM tcount_tbl;
+---------------+--------------+
| runoob_author | runoob_count |
+---------------+--------------+
| 菜鸟教程 | 10 |
| RUNOOB.COM | 20 |
| Google | 22 |
+---------------+--------------+
3 rows in set (0.01 sec)
mysql> SELECT * from runoob_tbl;
+-----------+---------------+---------------+-----------------+
| runoob_id | runoob_title | runoob_author | submission_date |
+-----------+---------------+---------------+-----------------+
| 1 | 学习 PHP | 菜鸟教程 | 2017-04-12 |
| 2 | 学习 MySQL | 菜鸟教程 | 2017-04-12 |
| 3 | 学习 Java | RUNOOB.COM | 2015-05-01 |
| 4 | 学习 Python | RUNOOB.COM | 2016-03-06 |
| 5 | 学习 C | FK | 2017-04-05 |
+-----------+---------------+---------------+-----------------+
5 rows in set (0.01 sec)
连接以上两张表来读取runoob_tbl表中所有runoob_author字段在tcount_tbl表对应的runoob_count字段值:
mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count
FROM
runoob_tbl a
INNER JOIN
tcount_tbl b
ON a.runoob_author = b.runoob_author;
+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1 | 菜鸟教程 | 10 |
| 2 | 菜鸟教程 | 10 |
| 3 | RUNOOB.COM | 20 |
| 4 | RUNOOB.COM | 20 |
+-------------+-----------------+----------------+
4 rows in set (0.00 sec)
MySQL LEFT JOIN 会读取左边数据表的全部数据,即便右边表无对应数据。
使用LEFT JOIN
,该语句会读取左边的数据表 runoob_tbl 的所有选取的字段数据,即便在右侧表 tcount_tbl中 没有对应的 runoob_author 字段值。
mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count
FROM
runoob_tbl a
LEFT JOIN
tcount_tbl b
ON
a.runoob_author = b.runoob_author;
+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1 | 菜鸟教程 | 10 |
| 2 | 菜鸟教程 | 10 |
| 3 | RUNOOB.COM | 20 |
| 4 | RUNOOB.COM | 20 |
| 5 | FK | NULL |
+-------------+-----------------+----------------+
5 rows in set (0.01 sec)
MySQL RIGHT JOIN 会读取右边数据表的全部数据,即便左边边表无对应数据。
使用
RIGHT JOIN
,该语句会读取右边的数据表 tcount_tbl 的所有选取的字段数据,即便在左侧表 runoob_tbl
中没有对应的runoob_author 字段值。
mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count
FROM
runoob_tbl a
RIGHT JOIN
tcount_tbl b
ON
a.runoob_author = b.runoob_author;
+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1 | 菜鸟教程 | 10 |
| 2 | 菜鸟教程 | 10 |
| 3 | RUNOOB.COM | 20 |
| 4 | RUNOOB.COM | 20 |
| NULL | NULL | 22 |
+-------------+-----------------+----------------+
5 rows in set (0.01 sec)
我们已经知道 MySQL 使用 SQL SELECT 命令及 WHERE 子句来读取数据表中的数据,但是当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作。
为了处理这种情况,MySQL提供了三大运算符:
查找数据表中某列是否为 NULL,必须使用 IS NULL 和 IS NOT NULL,如下实例:
SELECT * FROM ctf WHERE ctf_test IS NULL;
SELECT * FROM ctf WHERE ctf_test IS NOT NULL;
在前面的章节我们已经了解到MySQL可以通过 LIKE …% 来进行模糊匹配。
MySQL 同样也支持其他正则表达式的匹配, MySQL中使用 REGEXP 操作符来进行正则表达式匹配。
如下是几个例子:
查找name字段中以’ctf’为开头的所有数据:
mysql> SELECT name FROM person WHERE name REGEXP '^ctf';
查找name字段中以’ok’为结尾的所有数据:
mysql> SELECT name FROM person WHERE name REGEXP 'ok$';
查找name字段中包含’mar’字符串的所有数据:
mysql> SELECT name FROM person WHERE name REGEXP 'mar';
查找name字段中以元音字符开头或以’ok’字符串结尾的所有数据:
mysql> SELECT name FROM person WHERE name REGEXP '^[aeiou]|ok$';
MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!
一般来说,事务是必须满足4个条件(ACID):原子性(或称不可分割性)、一致性、隔离性(又称独立性)、持久性
原子性:一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有执行过一样。
一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏
隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交、读提交、可重复读和串行化。
持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
MYSQL 事务处理主要有两种方法:
用 BEGIN, ROLLBACK, COMMIT来实现
- BEGIN 开始一个事务
- ROLLBACK 事务回滚
- COMMIT 事务确认
直接用 SET 来改变 MySQL 的自动提交模式
- SET AUTOCOMMIT=0 禁止自动提交
- SET AUTOCOMMIT=1 开启自动提交
导出数据实例,Windows下:
mysqldump -u root -p text > output.sql #无需登录,导出text数据库output.sql文件到当前bin目录下
mysqldump -u 用户名 -p 数据库名 表名> 导出的文件名
#导出数据库只其中一个表
导入数据:
进入mysql数据库控制台,如
mysql -u root -p
mysql>use 数据库
然后使用source命令,后面参数为脚本文件(如这里用到的.sql)
mysql>source output.sql
Linux下Mysql导入数据:
# source + sql文件地址
source /home/SQL/mmall.sql
#字符串
CHAR_LENGTH(s) #返回字符串 s 的字符数
CHARACTER_LENGTH(s) #返回字符串 s 的字符数
FORMAT(x,n) #将数字 x 进行格式化,将 x 保留到小数点后 n 位,最后一位四舍五入
LEFT(s,n) #返回字符串 s 的前 n 个字符
RIGHT(s,n) #返回字符串 s 的后 n 个字符
REVERSE(s) #将字符串s的顺序反过来
#数字
MAX(expression) #返回字段 expression 中的最大值
MIN(expression) #返回字段 expression 中的最小值
日期函数
CURDATE()
CURRENT_DATE() #返回当前日期
SELECT CURDATE();
-> 2018-09-19
CURRENT_TIME() #返回当前时间
SELECT CURRENT_TIME();
-> 19:59:02
NOW()
LOCALTIMESTAMP()
LOCALTIME()
CURRENT_TIMESTAMP() #返回当前日期和时间
SELECT CURRENT_TIMESTAMP()
-> 2018-09-19 20:57:43
DAY(d) #返回日期值 d 的日期部分
SELECT DAY("2017-06-15");
-> 15
DAYNAME(d) #返回日期 d 是星期几,如 Monday,Tuesday
SELECT DAYNAME('2022-01-12 11:11:11')
->Wednesday
DAYOFMONTH(d) #计算日期 d 是本月的第几天
SELECT DAYOFMONTH('2022-01-12 11:11:11')
->12
DAYOFYEAR(d) #计算日期 d 是本年的第几天
SELECT DAYOFYEAR('2011-11-11 11:11:11')
->315
YEAR(d) #返回年份
SELECT YEAR("2022-01-12");
-> 2022
版权声明:本文教程基于菜鸟教程