ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

【2022-08-18】mysql基础知识(五)

2022-08-18 21:34:22  阅读:139  来源: 互联网

标签:student -- 18 08 cursor 2022 where id select


一、下载安装包

Navicat官网下载地址:https://www.navicat.com.cn/

二、解压安装包

三、安装过程

1. 双击执行下载好的exe安装包

2. 点击下一步

3. 选择同意协议

4. 选择软件安装位置

5. 直接点击下一步

6. 是否创建桌面快捷方式图标

7. 选择安装程序

8. 完成软件安装

9. 破解教程

https://www.jb51.net/article/199496.htm

多表查询练习题

1、查询所有的课程的名称以及对应的任课老师姓名

# 1.先确定需要几张表 课程表 老师表
# 2.简单查看每张表中的数据
-- select * from course;
-- select * from teacher;
# 3.思考查询逻辑  多表查询(连表操作)
-- SELECT
-- 	course.cname AS '课程',
-- 	teacher.tname AS '讲师姓名' 
-- FROM
-- 	course
-- 	INNER JOIN teacher ON course.teacher_id = teacher.tid;

4、查询平均成绩大于八十分的同学的姓名和平均成绩


# 1.先确定需要几张表 成绩表 学生表
# 2.简单查看表中数据
-- select * from student;
-- select * from score;
# 3.先查询成绩表中平均成绩大于80分的数据
# 3.1.按照学生编号分组 利用聚合函数avg求出所有学生编号对应的平均成绩
-- select student_id,avg(num) from score group by student_id;
# 3.2.基于上述分组之后的结果筛选出平均成绩大于80的数据
-- select student_id,avg(num) from score group by student_id having avg(num) > 80;
/*针对select后面通过函数或者表达式编写的字段为了后续取值方便 一般需要重命名成普通字段*/
-- select student_id,avg(num) as avg_num from score group by student_id having avg(num) > 80;
# 4.最终的结果需要从上述sql语句的结果表中获取一个字段和学生表中获取一个字段
-- select * from student inner join (select student_id,avg(num) as avg_num from score group by student_id having avg(num) > 80) as t1
-- on student.sid = t1.student_id;
/*将SQL语句当做表来使用 连接的时候需要使用as起表名*/
-- SELECT
-- 	student.sname,
-- 	t1.avg_num 
-- FROM
-- 	student
-- 	INNER JOIN ( SELECT student_id, avg( num ) AS avg_num FROM score GROUP BY student_id HAVING avg( num ) > 80 ) AS t1 ON student.sid = t1.student_id;

7、查询没有报李平老师课的学生姓名


# 1.先确定需要用到的表 老师表 课程表 分数表 学生表
# 2.简单的查看表中数据
# 3.两种解题思路:
-- 直接查其他老师教的课然后一步步查到学生
-- 查报了李平老师课的学生编号然后取反即可(推荐)
# 4.先获取李平老师教授的课程id号
-- select tid from teacher where tname='李平老师'
# 5.子查询获取课程编号
-- select cid from course where teacher_id=(select tid from teacher where tname='李平老师')
# 6.根据课程编号去成绩表中筛选出所有报了课程编号的数据
-- select distinct student_id from score where course_id in (select cid from course where teacher_id=(select tid from teacher where tname='李平老师'))
# 7.根据上述学生id号去学生表中取反 获取没有报李平老师课程的学生姓名
-- SELECT
-- 	sname 
-- FROM
-- 	student 
-- WHERE
-- 	sid NOT IN ( SELECT DISTINCT student_id FROM score WHERE course_id IN ( SELECT cid FROM course WHERE teacher_id =( SELECT tid FROM teacher WHERE tname = '李平老师' )) )

8、查询没有同时选修物理课程和体育课程的学生姓名(只要选了其中一门的 两门都选和都没选的都不要)


# 1.先确定需要几张表
# 2.简单的查看表里面的数据
# 3.先获取物理和体育课程的id号
-- select cid from course where cname in ('物理','体育');
# 4.根据课程的id号先去成绩表中过滤掉没有选择这些课程的数据
-- select * from score where course_id in (select cid from course where cname in ('物理','体育'))
# 5.基于上述表统计每个学生编号报了几门课
-- select score.student_id from score where course_id in (select cid from course where cname in ('物理','体育'))
-- group by score.student_id having count(score.course_id) = 1
# 6.根据上述学生id获取学生姓名
-- select sname from student where sid in (select score.student_id from score where course_id in (select cid from course where cname in ('物理','体育'))
-- group by score.student_id having count(score.course_id) = 1)

9、查询挂科超过两门(包括两门)的学生姓名和班级


# 1.先筛选出分数小于60的数据
-- select * from score where num < 60;
# 2.按照学生id分组然后计数即可
-- select student_id from score where num < 60 group by student_id having count(course_id) >= 2;
# 3.先连接班级表和学生表
-- select * from class inner join student on class.cid = student.class_id;
# 4.合并23的SQL
SELECT
	class.caption,
	student.sname 
FROM
	class
	INNER JOIN student ON class.cid = student.class_id 
WHERE
	student.sid IN ( SELECT student_id FROM score WHERE num < 60 GROUP BY student_id HAVING count( course_id ) >= 2 );

Python操作mysql

准备工作

下载固定模块: 
方法一:命令下载 pip isntall pymysql
方法二:借助于pycharm下载

模块的基本使用

import pymysql            # 导入模块

# 1.连接服务端
conn = pymysql.connect(
    host='127.0.0.1',     # 本地回环地址
    port=3306,            # mysql默认端口号
    user='root',          # 用户名
    password='123456',    # 密码
    database='db5',       # 指定数据库
    charset='utf8mb4',    # 指定编码格式
)

# 2.产生一个游标对象(相当于在cmd界面打开mysql,等待输入命令)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
# 3.编写SQL语句
sql = 'select * from userinfo'   # pycharm自动提示,不用管
# 4.发送给服务端
cursor.execute(sql)
# 5.获取返回的结果
res = cursor.fetchall()
print(res)


autocommit二次确认

import pymysql            # 导入模块

# 1.连接服务端
conn = pymysql.connect(
    host='127.0.0.1',     # 本地回环地址
    port=3306,            # mysql默认端口号
    user='root',          # 用户名
    password='123456',    # 密码
    database='db5',       # 指定数据库
    charset='utf8mb4',    # 指定编码格式
    autocommit=True       # 执行增、改、删操作自动执行conn.commit
)

# 2.产生一个游标对象(相当于在cmd界面打开mysql,等待输入命令)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
# 3.编写SQL语句
sql = 'select * from userinfo'   # pycharm自动提示,不用管
# 4.发送给服务端
cursor.execute(sql)
# 5.获取返回的结果
res = cursor.fetchall()
print(res)



总结:
# 1.查询语句可以正常执行并获取结果
# cursor.execute(sql1)
# 2.插入语句能够执行 但是并没有影响表数据
# cursor.execute(sql2,('jackson',666))
# 3.更新语句能够执行 但是并没有影响表数据
# res = cursor.execute(sql3)
# print(res)
# 4.删除语句能够执行 但是并没有影响表数据
# res = cursor.execute(sql4)
# print(res)
 
解释:在针对增删改查操作时他们的重要程度不一样(级别不一样)  查功能的级别是最低的,增删改都是要影响到数据信息的,pymysql规定必须需要一个二次确认才可生效。
 
怎么进行二次确认呢?
关键字:commit()
 
在执行增删改操作的下面 执行 conn.commit()命令进行二次确认
 
 
这样感觉每次执行增删改操作都要执行conn.commit()命令非常的麻烦.
这里就用到我们开头提到的自动二次确认 autocommit :
使用:
	在创建pymysql添加: autocommit=True

获取结果

cursor.fetchone()   # 获取结果集中一条数据
cursor.fetchall()   # 获取结果集中所有数据
cursor.fetchmany()  # 获取结果集中指定条的数据
'''类似于文件光标的概念'''
cursor.scroll(2, mode='relative')  # 基于当前位置往后移动
cursor.scroll(0, mode='absolute')  # 基于数据集开头的位置往后移动

SQL注入问题

import pymysql  # 导入模块

# 1.连接服务端,使用数据库完成一个简单的登录功能
conn = pymysql.connect(
    host='127.0.0.1',  # 本地回环地址
    port=3306,  # mysql默认端口号
    user='root',  # 用户名
    password='123456',  # 密码
    database='db5',  # 指定数据库
    charset='utf8mb4',  # 指定编码格式
    autocommit=True  # 执行增、改、删操作自动执行conn.commit
)

# 2.产生一个游标对象(相当于在cmd界面打开mysql,等待输入命令)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
# 3.获取用户输入
username = input('请输入您的用户名>>>:').strip()
password = input('请输入您的登录密码>>>:').strip()
# 4.编写SQL语句
sql = "select * from userinfo where name='%s' and pwd='%s'" % (username, password)  # pycharm自动提示,不用管
# 5.发送给服务端,执行SQL语句
cursor.execute(sql)
# 6.获取返回的结果
res = cursor.fetchall()  # 获取所有的数据,结果是列表套字典
# print(res)
if res:
    print('登录成功')
else:
    print('用户名或密码错误')




SQL注入
	select * from userinfo where name='jason' -- haha' and pwd=''
	select * from userinfo where name='xyz' or 1=1  -- heihei' and pwd=''
	
这就是sql注入问题:
 
SQL注入问题的产生:
    就是通过一些特殊符号的组合 达到某些特定的效果从而避免常规的逻辑
SQL注入问题如何解决:
    execute方法自动帮你解决
    
  
解决方法:

import pymysql  # 导入模块

# 1.连接服务端,使用数据库完成一个简单的登录功能
conn = pymysql.connect(
    host='127.0.0.1',  # 本地回环地址
    port=3306,  # mysql默认端口号
    user='root',  # 用户名
    password='123456',  # 密码
    database='db5',  # 指定数据库
    charset='utf8mb4',  # 指定编码格式
    autocommit=True  # 执行增、改、删操作自动执行conn.commit
)

# 2.产生一个游标对象(相当于在cmd界面打开mysql,等待输入命令)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
# 3.获取用户输入
username = input('请输入您的用户名>>>:').strip()
password = input('请输入您的登录密码>>>:').strip()
# 4.编写SQL语句
sql = "select * from userinfo where name=%s and pwd=%s"   
# 5.发送给服务端,执行SQL语句
cursor.execute(sql, (username, password))           	  # 自动识别%s 并自动过滤各种符合 最后合并数据
# 6.获取返回的结果
res = cursor.fetchall()  # 获取所有的数据,结果是列表套字典
# print(res)
if res:
    print('登录成功')
    print(res)
else:
    print('用户名或密码错误')

补充 executemany():

定义: 在我们要插入很多数据的时候 就要使用到executemany()
 
使用:
cursor.executemany(sql,[('tom1',111),('tom2',222),('tom3',333)])
 
验证:

知识点补充

1.as语法
	给字段起别名、起表名
2.comment语法
	给表、字段添加注释信息
 	create table server(id int) comment '这个server意思是服务器表'
	create table t1(
    	id int comment '用户编号',
       name varchar(16) comment '用户名'
    ) comment '用户表';
	"""
	查看注释的地方
		show create table 
		use information_schema
	"""
3.concat、concat_ws语法
	concat用于分组之前多个字段数据的拼接
 	concat_ws如果有多个字段 并且分隔符一致 可以使用该方法减少代码
4.exists语法
	select * from userinfo where exists (select * from department where id<100)
	exists后面的sql语句如果有结果那么执行前面的sql语句
	如果没有结果则不执行

标签:student,--,18,08,cursor,2022,where,id,select
来源: https://www.cnblogs.com/dy12138/p/16600178.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有