知识点一: 筛选条件
知识点二: 排序、去重
知识点三: 聚合与分组
知识点四: 限制与分页
执行环境:Ubuntu16.04_server_32bit
运行软件: mysql
执行命令进入mysql命令行:
pyvip@Vip:~$ mysql -uroot -pqwe123
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 64
Server version: 5.7.21-0ubuntu0.16.04.1 (Ubuntu)
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
数据准备:
# 学生表
CREATE TABLE students (
number CHAR(9), # 学号
name VARCHAR(20), # 姓名
klass VARCHAR(10), # 班级
age INT, # 年龄
birth DATE # 生日
);
INSERT INTO students
VALUES ('201804001', '刘一', 19, 16, '2002-01-01'),
('201804002', '陈二', 18, 17, '2001-01-02'),
('201804003', '张三', 19, 18, '2000-01-03'),
('201804004', '李四', 19, 19, '2001-01-04'),
('201804005', '王五', 19, 16, '2002-01-05'),
('201804006', '赵六', 18, 19, '1999-01-06'),
('201804007', '孙七', 19, 17, '2001-01-07'),
('201804008', '周八', 19, 18, '2000-01-08'),
('201804009', '吴九', 18, 17, '2001-01-09'),
('201804010', '郑十', 19, 18, '2000-01-10');
select * from students;
#结果打印:
+----+-----------+--------+------+------------+
| id | number | name | age | birth |
+----+-----------+--------+------+------------+
| 1 | 201804001 | 刘一 | 16 | 2002-01-01 |
| 2 | 201804002 | 陈二 | 17 | 2001-01-02 |
| 3 | 201804003 | 张三 | 18 | 2000-01-03 |
| 4 | 201804004 | 李四 | 19 | 2001-01-04 |
| 5 | 201804005 | 王五 | 20 | 2000-01-05 |
| 6 | 201804006 | 赵六 | 21 | 1999-01-06 |
| 7 | 201804007 | 孙七 | 22 | 1999-01-07 |
| 8 | 201804008 | 周八 | 23 | 1999-01-08 |
| 9 | 201804009 | 吴九 | 24 | 1999-01-09 |
| 10 | 201804010 | 郑十 | 25 | 1999-01-10 |
+----+-----------+--------+------+------------+
10 rows in set (0.11 sec)
问题一: 除了“=”以外,还能有其他的运算符嘛 ?
问题二: 如果有多个条件,该如何做 ?
问题三: 如何查询一个范围中的数据?
问题四: MySQL可以做模糊匹配嘛 ?
# 条件筛选
INSERT INTO students VALUES ('201804011', NULL, NULL, NULL, NULL);
mysql> select * from students;
+-----------+--------+-------+------+------------+
| number | name | klass | age | birth |
+-----------+--------+-------+------+------------+
| 201804001 | 刘一 | 19 | 16 | 2002-01-01 |
| 201804002 | 陈二 | 18 | 17 | 2001-01-02 |
| 201804003 | 张三 | 19 | 18 | 2000-01-03 |
| 201804004 | 李四 | 19 | 19 | 2001-01-04 |
| 201804005 | 王五 | 19 | 16 | 2002-01-05 |
| 201804006 | 赵六 | 18 | 19 | 1999-01-06 |
| 201804007 | 孙七 | 19 | 17 | 2001-01-07 |
| 201804008 | 周八 | 19 | 18 | 2000-01-08 |
| 201804009 | 吴九 | 18 | 17 | 2001-01-09 |
| 201804010 | 郑十 | 19 | 18 | 2000-01-10 |
| 201804011 | NULL | NULL | NULL | NULL |
+-----------+--------+-------+------+------------+
11 rows in set (0.00 sec)
mysql> SELECT * FROM students WHERE name<>'李四';
+-----------+--------+-------+------+------------+
| number | name | klass | age | birth |
+-----------+--------+-------+------+------------+
| 201804001 | 刘一 | 19 | 16 | 2002-01-01 |
| 201804002 | 陈二 | 18 | 17 | 2001-01-02 |
| 201804003 | 张三 | 19 | 18 | 2000-01-03 |
| 201804005 | 王五 | 19 | 16 | 2002-01-05 |
| 201804006 | 赵六 | 18 | 19 | 1999-01-06 |
| 201804007 | 孙七 | 19 | 17 | 2001-01-07 |
| 201804008 | 周八 | 19 | 18 | 2000-01-08 |
| 201804009 | 吴九 | 18 | 17 | 2001-01-09 |
| 201804010 | 郑十 | 19 | 18 | 2000-01-10 |
+-----------+--------+-------+------+------------+
9 rows in set (0.01 sec)
mysql> SELECT * FROM students WHERE name<>NULL;
Empty set (0.00 sec)
mysql> SELECT * FROM students WHERE name=NULL;
Empty set (0.00 sec)
mysql> SELECT * FROM students WHERE name IS NULL;
+-----------+------+-------+------+-------+
| number | name | klass | age | birth |
+-----------+------+-------+------+-------+
| 201804011 | NULL | NULL | NULL | NULL |
+-----------+------+-------+------+-------+
1 row in set (0.00 sec)
mysql> SELECT * FROM students WHERE name IS NOT NULL;
+-----------+--------+-------+------+------------+
| number | name | klass | age | birth |
+-----------+--------+-------+------+------------+
| 201804001 | 刘一 | 19 | 16 | 2002-01-01 |
| 201804002 | 陈二 | 18 | 17 | 2001-01-02 |
| 201804003 | 张三 | 19 | 18 | 2000-01-03 |
| 201804004 | 李四 | 19 | 19 | 2001-01-04 |
| 201804005 | 王五 | 19 | 16 | 2002-01-05 |
| 201804006 | 赵六 | 18 | 19 | 1999-01-06 |
| 201804007 | 孙七 | 19 | 17 | 2001-01-07 |
| 201804008 | 周八 | 19 | 18 | 2000-01-08 |
| 201804009 | 吴九 | 18 | 17 | 2001-01-09 |
| 201804010 | 郑十 | 19 | 18 | 2000-01-10 |
+-----------+--------+-------+------+------------+
10 rows in set (0.00 sec)
连续范围: BETWEEN a AND b
代码验证:
mysql> mysql> SELECT * FROM students WHERE age BETWEEN 17 AND 18;
+-----------+--------+-------+------+------------+
| number | name | klass | age | birth |
+-----------+--------+-------+------+------------+
| 201804002 | 陈二 | 18 | 17 | 2001-01-02 |
| 201804003 | 张三 | 19 | 18 | 2000-01-03 |
| 201804007 | 孙七 | 19 | 17 | 2001-01-07 |
| 201804008 | 周八 | 19 | 18 | 2000-01-08 |
| 201804009 | 吴九 | 18 | 17 | 2001-01-09 |
| 201804010 | 郑十 | 19 | 18 | 2000-01-10 |
+-----------+--------+-------+------+------------+
6 rows in set (0.03 sec)
mysql> SELECT * FROM students WHERE age IN (16,19);
+-----------+--------+-------+------+------------+
| number | name | klass | age | birth |
+-----------+--------+-------+------+------------+
| 201804001 | 刘一 | 19 | 16 | 2002-01-01 |
| 201804004 | 李四 | 19 | 19 | 2001-01-04 |
| 201804005 | 王五 | 19 | 16 | 2002-01-05 |
| 201804006 | 赵六 | 18 | 19 | 1999-01-06 |
+-----------+--------+-------+------+------------+
4 rows in set (0.00 sec)
常用通配符:
代码验证:
mysql> INSERT INTO students VALUES ('201804012', '李世民', NULL, NULL, NULL);
Query OK, 1 row affected (0.02 sec)
mysql> SELECT * FROM students name LIKE '李%';
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LIKE '李%'' at line 1
mysql> SELECT * FROM students WHERE name LIKE '李%';
+-----------+-----------+-------+------+------------+
| number | name | klass | age | birth |
+-----------+-----------+-------+------+------------+
| 201804004 | 李四 | 19 | 19 | 2001-01-04 |
| 201804012 | 李世民 | NULL | NULL | NULL |
+-----------+-----------+-------+------+------------+
2 rows in set (0.00 sec)
mysql> SELECT * FROM students WHERE name LIKE '李_';
+-----------+--------+-------+------+------------+
| number | name | klass | age | birth |
+-----------+--------+-------+------+------------+
| 201804004 | 李四 | 19 | 19 | 2001-01-04 |
+-----------+--------+-------+------+------------+
1 row in set (0.00 sec)
问题一: 如果希望查询的结果依据某列排序该怎么做 ?
问题二: 是否支持正序与反序排列 ?
问题三: 如果只查询部分列,能否去重 ?
代码样例:
SELECT columns FROM tb_name ORDER BY ord_col_1 [asc/desc];
代码验证:
mysql> SELECT * FROM students ORDER BY age;
+-----------+-----------+-------+------+------------+
| number | name | klass | age | birth |
+-----------+-----------+-------+------+------------+
| 201804011 | NULL | NULL | NULL | NULL |
| 201804012 | 李世民 | NULL | NULL | NULL |
| 201804001 | 刘一 | 19 | 16 | 2002-01-01 |
| 201804005 | 王五 | 19 | 16 | 2002-01-05 |
| 201804002 | 陈二 | 18 | 17 | 2001-01-02 |
| 201804007 | 孙七 | 19 | 17 | 2001-01-07 |
| 201804009 | 吴九 | 18 | 17 | 2001-01-09 |
| 201804003 | 张三 | 19 | 18 | 2000-01-03 |
| 201804008 | 周八 | 19 | 18 | 2000-01-08 |
| 201804010 | 郑十 | 19 | 18 | 2000-01-10 |
| 201804004 | 李四 | 19 | 19 | 2001-01-04 |
| 201804006 | 赵六 | 18 | 19 | 1999-01-06 |
+-----------+-----------+-------+------+------------+
12 rows in set (0.01 sec)
mysql> SELECT * FROM students ORDER BY age DESC;
+-----------+-----------+-------+------+------------+
| number | name | klass | age | birth |
+-----------+-----------+-------+------+------------+
| 201804004 | 李四 | 19 | 19 | 2001-01-04 |
| 201804006 | 赵六 | 18 | 19 | 1999-01-06 |
| 201804003 | 张三 | 19 | 18 | 2000-01-03 |
| 201804008 | 周八 | 19 | 18 | 2000-01-08 |
| 201804010 | 郑十 | 19 | 18 | 2000-01-10 |
| 201804002 | 陈二 | 18 | 17 | 2001-01-02 |
| 201804007 | 孙七 | 19 | 17 | 2001-01-07 |
| 201804009 | 吴九 | 18 | 17 | 2001-01-09 |
| 201804001 | 刘一 | 19 | 16 | 2002-01-01 |
| 201804005 | 王五 | 19 | 16 | 2002-01-05 |
| 201804011 | NULL | NULL | NULL | NULL |
| 201804012 | 李世民 | NULL | NULL | NULL |
+-----------+-----------+-------+------+------------+
12 rows in set (0.00 sec)
数据重复的定义:两条数据其对应列都相等。
代码样例:
SELECT DISTINCT columns FROM tb_name;
通常数据库会设置主键,因此直接查询是不会出现重复的,一般情况下查询非主键的部分列时
才会使用DISTINCT
mysql> SELECT DISTINCT klass ,age FROM students;
+-------+------+
| klass | age |
+-------+------+
| 19 | 16 |
| 18 | 17 |
| 19 | 18 |
| 19 | 19 |
| 18 | 19 |
| 19 | 17 |
+-------+------+
6 rows in set (0.00 sec)
mysql> SELECT klass ,age FROM students;
+-------+------+
| klass | age |
+-------+------+
| 19 | 16 |
| 18 | 17 |
| 19 | 18 |
| 19 | 19 |
| 19 | 16 |
| 18 | 19 |
| 19 | 17 |
| 19 | 18 |
| 18 | 17 |
| 19 | 18 |
+-------+------+
10 rows in set (0.00 sec)
问题一: 仅从文字上看,你认为聚合是什么意思 ?
问题二: 聚合通常是为了什么目的 ?
问题三: 分组对于聚合而言意味着什么 ?
问题四: 能否对筛选聚合值 ?
代码验证:
mysql> SELECT COUNT(*) FROM students;
+----------+
| COUNT(*) |
+----------+
| 10 |
+----------+
1 row in set (0.03 sec)
mysql> SELECT MAX(age) FROM students;
+----------+
| MAX(age) |
+----------+
| 19 |
+----------+
1 row in set (0.02 sec)
mysql> SELECT MIN(age) FROM students;
+----------+
| MIN(age) |
+----------+
| 16 |
+----------+
1 row in set (0.00 sec)
mysql> SELECT SUM(age) FROM students;
+----------+
| SUM(age) |
+----------+
| 175 |
+----------+
1 row in set (0.00 sec)
mysql> SELECT AVG(age) FROM students;
+----------+
| AVG(age) |
+----------+
| 17.5000 |
+----------+
1 row in set (0.00 sec)
代码样例:
SELECT group_column
, aggregations FROM tb_name GROUP group_column
;
注:在分组的情况下,只应该出现分组列和聚合列其他的列没有意义 !
代码验证:
mysql> SELECT klass ,AVG(age) FROM students GROUP BY klass;
+-------+----------+
| klass | AVG(age) |
+-------+----------+
| 18 | 17.6667 |
| 19 | 17.4286 |
+-------+----------+
2 rows in set (0.01 sec)
以上语句即表示:以klass为分组查询各个分组的平均值
代码样例:
SELECT group_column
, aggregations FROM tb_name GROUP group_column
HAVING conditions
;
关于筛选关键字的总结:
假如说,一个查询中同时包含了ON、WHERE、HAVING那么它们的执行顺序是:
代码验证:
mysql> SELECT klass, COUNT(*) FROM students GROUP BY klass HAVING COUNT(*)>4;
+-------+----------+
| klass | COUNT(*) |
+-------+----------+
| 19 | 7 |
+-------+----------+
1 row in set (0.01 sec)
mysql> SELECT klass, COUNT(*) FROM students GROUP BY klass WHERE COUNT(*)>4;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE COUNT(*)>4' at line 1
关于ON
与WHERE
关键字的筛选次序在Python-mysql数据库基础补充的连接查询中有叙述由此我在做一下总结:
eg:
SELECT subject_number, grade
FROM ( students JOIN grades ON students.number=grades.student_number )
WHERE name='张三';
有这条语句可以得出:关于ON
与WHERE
关键字的筛选次序是先是筛选: ON 然后筛选: WHERE,再根据上一条代码验证可以得出:三条关键字在运行过程中的先后次序为ON
>WHERE
>HANING
问题一: 如果一次性不需要那么多数据,该如何做 ?
问题二: 能否从指定位置开始取 ?
问题三: 分页是如何做的 ?
代码样例:
count
start
, count
代码验证:
mysql> SELECT * FROM students;
+-----------+--------+-------+------+------------+
| number | name | klass | age | birth |
+-----------+--------+-------+------+------------+
| 201804001 | 刘一 | 19 | 16 | 2002-01-01 |
| 201804002 | 陈二 | 18 | 17 | 2001-01-02 |
| 201804003 | 张三 | 19 | 18 | 2000-01-03 |
| 201804004 | 李四 | 19 | 19 | 2001-01-04 |
| 201804005 | 王五 | 19 | 16 | 2002-01-05 |
| 201804006 | 赵六 | 18 | 19 | 1999-01-06 |
| 201804007 | 孙七 | 19 | 17 | 2001-01-07 |
| 201804008 | 周八 | 19 | 18 | 2000-01-08 |
| 201804009 | 吴九 | 18 | 17 | 2001-01-09 |
| 201804010 | 郑十 | 19 | 18 | 2000-01-10 |
+-----------+--------+-------+------+------------+
10 rows in set (0.00 sec)
mysql> SELECT * FROM students LIMIT 3;
+-----------+--------+-------+------+------------+
| number | name | klass | age | birth |
+-----------+--------+-------+------+------------+
| 201804001 | 刘一 | 19 | 16 | 2002-01-01 |
| 201804002 | 陈二 | 18 | 17 | 2001-01-02 |
| 201804003 | 张三 | 19 | 18 | 2000-01-03 |
+-----------+--------+-------+------+------------+
3 rows in set (0.01 sec)
mysql> SELECT * FROM students LIMIT 3,3;
+-----------+--------+-------+------+------------+
| number | name | klass | age | birth |
+-----------+--------+-------+------+------------+
| 201804004 | 李四 | 19 | 19 | 2001-01-04 |
| 201804005 | 王五 | 19 | 16 | 2002-01-05 |
| 201804006 | 赵六 | 18 | 19 | 1999-01-06 |
+-----------+--------+-------+------+------------+
3 rows in set (0.01 sec)
代码样例:
SELECT columns FROM tb_name LIMIT (n
-1)*m
, m
在python里面定义俩变量:
n
表示第几页m
每页多少个代码验证:
代码编辑器:pycharm2016
运行环境:Ubuntu16.04_server_32bit(python3)
任务:用Python实现分页查询
(pycharm远程连接Ubuntu16.04_server_32bit虚拟环境下代码实现
也可以直接在Ubuntu16.04_server_32bit运行)
import pymysql
db_config = {
'host': '127.0.0.1',
'user': 'root',
'password': 'qwe123',
'db': 'python3',
'charset': 'utf8',
}
def sql_check(n,m):
cur = conn.cursor()
sql = 'SELECT * FROM student LIMIT %s,%s' %((n-1)*m,m)
sql2 = 'SELECT * FROM student'
rv = cur.execute(sql)
res = cur.fetchall()
for entry in res:
print(entry)
cur.close()
conn = pymysql.connect(**db_config)
try:
while True :
n = input('请输入查询的页数:')
if n == 'q':
break
if n.isdigit():
sql_check(int(n),3)
else:
print("输入的不是数字!!!!")
except Exception as e :
print('执行过程中发生了异常',e)
conn.rollback()
finally:
conn.commit()
conn.close()
结果打印:
ssh://pyvip@192.168.206.128:22/home/pyvip/.virtualenvs/py3env/bin/python -u /home/pyvip/py_case/mysql_wege.py
请输入查询的页数:1
1
('201804001', '刘一', 16, datetime.date(2002, 1, 1))
('201804002', '陈二', 17, datetime.date(2001, 1, 2))
('201804003', '张三', 18, datetime.date(2000, 1, 3))
请输入查询的页数:2
2
('201804004', '李四', 19, datetime.date(2001, 1, 4))
('201804005', '王五', 20, datetime.date(2000, 1, 5))
('201804006', '赵六', 21, datetime.date(1999, 1, 6))
请输入查询的页数:3
3
('201804007', '孙七', 22, datetime.date(1999, 1, 7))
('201804008', '周八', 23, datetime.date(1999, 1, 8))
('201804009', '吴九', 24, datetime.date(1999, 1, 9))
请输入查询的页数:4
4
('201804010', '郑十', 25, datetime.date(1999, 1, 10))
请输入查询的页数:q
q
进程已结束,退出代码0