create table dep(
id int primary key auto_increment,
name varchar(16),
work varchar(16)
);
create table emp(
id int primary key auto_increment,
name varchar(16),
salary float,
dep_id int
);
insert into dep values(1, '市场部', '销售'), (2, '教学部', '授课'), (3, '管理部', '开车');
insert into emp(name, salary, dep_id) values('egon', 3.0, 2),('yanghuhu', 2.0, 2),('sanjiang', 10.0, 1),('owen', 88888.0, 2),('liujie', 8.0, 1),('yingjie', 1.2, 0);

多表数据

一.多表查询

1.笛卡尔积(交叉连接,不使用任何匹配条件)

'''
# 需求:
# 查看每位员工的部门的所有信息
select * from emp;
select * from dep; # 子查询, 最终结果只能显示单表的信息, 但需求是同时显示两张表的信息 => 先将两张表合成一张表
select * from emp where dep_id in (select id from dep); '''
'''
笛卡尔积: 集合 X{a, b} * Y{o, p, q} => Z{{a, o}, {a, p}, {a, q}, {b, o}, {b, p}, {b, q}}
交叉查询: select * from emp, dep; | select * from emp course join dep;
''' ''' 做了筛选, 结果<=完整数据, 非笛卡尔积
select * from emp, dep where db2.emp.dep_id = db2.dep.id; # 同sql语句上表现是从两张表拿数据
# 注意: 同时查询两张表形成新的表,可以称之为虚拟表, 原表与表之间可能存在重复字段, 同时使用时需要明确所属表,必要时还需明确所属数据库
'''

mysql> select * from emp,dep;
+----+----------+--------+--------+----+-----------+--------+
| id | name | salary | dep_id | id | name | work |
+----+----------+--------+--------+----+-----------+--------+
| 1 | egon | 3 | 2 | 1 | 市场部 | 销售 |
| 1 | egon | 3 | 2 | 2 | 教学部 | 授课 |
| 1 | egon | 3 | 2 | 3 | 管理部 | 开车 |
| 2 | yanghuhu | 2 | 2 | 1 | 市场部 | 销售 |
| 2 | yanghuhu | 2 | 2 | 2 | 教学部 | 授课 |
| 2 | yanghuhu | 2 | 2 | 3 | 管理部 | 开车 |
| 3 | sanjiang | 10 | 1 | 1 | 市场部 | 销售 |
| 3 | sanjiang | 10 | 1 | 2 | 教学部 | 授课 |
| 3 | sanjiang | 10 | 1 | 3 | 管理部 | 开车 |
| 4 | owen | 88888 | 2 | 1 | 市场部 | 销售 |
| 4 | owen | 88888 | 2 | 2 | 教学部 | 授课 |
| 4 | owen | 88888 | 2 | 3 | 管理部 | 开车 |
| 5 | liujie | 8 | 1 | 1 | 市场部 | 销售 |
| 5 | liujie | 8 | 1 | 2 | 教学部 | 授课 |
| 5 | liujie | 8 | 1 | 3 | 管理部 | 开车 |
| 6 | yingjie | 1.2 | 0 | 1 | 市场部 | 销售 |
| 6 | yingjie | 1.2 | 0 | 2 | 教学部 | 授课 |
| 6 | yingjie | 1.2 | 0 | 3 | 管理部 | 开车 |
+----+----------+--------+--------+----+-----------+--------+
18 rows in set (0.01 sec)

2.内连接:只连接匹配的行

# 找到两张表共有的部分相当于利用条件从笛卡尔积结果中筛选出了正确的结果
'''
inner join on 内连接:结果为两张表有对应关系的数据(emp有dep没有,emp没有dep有的记录均不会被虚拟表展示)
语法:左表 inner join 右表 on 两表有关联的字段的条件, on就是产生对于关系的(连接的依据)
eg:select * from emp inner join dep on emp.dep_id = dep.id;
'''
mysql> select * from emp inner join dep on emp.dep_id = dep.id;
+----+----------+--------+--------+----+-----------+--------+
| id | name | salary | dep_id | id | name | work |
+----+----------+--------+--------+----+-----------+--------+
| 1 | egon | 3 | 2 | 2 | 教学部 | 授课 |
| 2 | yanghuhu | 2 | 2 | 2 | 教学部 | 授课 |
| 3 | sanjiang | 10 | 1 | 1 | 市场部 | 销售 |
| 4 | owen | 88888 | 2 | 2 | 教学部 | 授课 |
| 5 | liujie | 8 | 1 | 1 | 市场部 | 销售 |
+----+----------+--------+--------+----+-----------+--------+
5 rows in set (0.00 sec)

3.左连接:优先显示左表全部记录

# 本质:在内连接的基础上增加左边有而右边没有的结果
'''
left join on
左连接:在内连接的基础上还保留左表特有的记录
语法:左表 left join 右表 on 两表有关联的字段的条件
eg:select emp.name '员工', dep.name '部门', dep.work '职责' from emp left join dep on emp.dep_id = dep.id;
'''
mysql> select emp.name '员工',dep.name '部门',dep.work '职责' from emp left join dep on emp.dep_id = dep.id;
+----------+-----------+--------+
| 员工 | 部门 | 职责 |
+----------+-----------+--------+
| sanjiang | 市场部 | 销售 |
| liujie | 市场部 | 销售 |
| egon | 教学部 | 授课 |
| yanghuhu | 教学部 | 授课 |
| owen | 教学部 | 授课 |
| yingjie | NULL | NULL |
+----------+-----------+--------+
6 rows in set (0.01 sec)

4.右连接:优先显示右表全部记录

# 本质:在内连接的基础上增加右边有而左边没有的结果
'''
right join on
右连接:在内连接的基础上还保留右表特有的记录
语法:左表 right join 右表 on 两表有关联的字段的条件
eg:select * from emp right join dep on emp.dep_id = dep.id;
''' '''
在连接语法join 前就是左表, 后就是右表
采用的是left关键词就是左连接, right关键词就是右连接, inner关键词就是内连接
'''
mysql> select * from emp right join dep on emp.dep_id = dep.id;
+------+----------+--------+--------+----+-----------+--------+
| id | name | salary | dep_id | id | name | work |
+------+----------+--------+--------+----+-----------+--------+
| 1 | egon | 3 | 2 | 2 | 教学部 | 授课 |
| 2 | yanghuhu | 2 | 2 | 2 | 教学部 | 授课 |
| 3 | sanjiang | 10 | 1 | 1 | 市场部 | 销售 |
| 4 | owen | 88888 | 2 | 2 | 教学部 | 授课 |
| 5 | liujie | 8 | 1 | 1 | 市场部 | 销售 |
| NULL | NULL | NULL | NULL | 3 | 管理部 | 开车 |
+------+----------+--------+--------+----+-----------+--------+
6 rows in set (0.00 sec)

5.全连接

# 全外连接:在内连接的基础上增加左边有右边没有的和右边有左边没有的结果
'''
全连接:在内连接的基础上分别保留这左表及右表特有的记录
语法:mysql没有full join on语法,但可以通过去重达到效果
eg:
select * from emp left join dep on emp.dep_id = dep.id
union
select * from emp right join dep on emp.dep_id = dep.id;
'''
mysql> select * from emp left join dep on emp.dep_id = dep.id
-> union
-> select * from emp right join dep on emp.dep_id = dep.id;
+------+----------+--------+--------+------+-----------+--------+
| id | name | salary | dep_id | id | name | work |
+------+----------+--------+--------+------+-----------+--------+
| 3 | sanjiang | 10 | 1 | 1 | 市场部 | 销售 |
| 5 | liujie | 8 | 1 | 1 | 市场部 | 销售 |
| 1 | egon | 3 | 2 | 2 | 教学部 | 授课 |
| 2 | yanghuhu | 2 | 2 | 2 | 教学部 | 授课 |
| 4 | owen | 88888 | 2 | 2 | 教学部 | 授课 |
| 6 | yingjie | 1.2 | 0 | NULL | NULL | NULL |
| NULL | NULL | NULL | NULL | 3 | 管理部 | 开车 |
+------+----------+--------+--------+------+-----------+--------+
7 rows in set (0.00 sec)
'''
1.查询每一位员工对应的工作职责
# 每一位员工 => 左表为emp表, 那么左表的所有数据均需要被保留, 所有采用左连接
=> 左表为dep表, 那么右表的所有数据均需要被保留, 所有采用右连接
# select emp.name, dep.work from emp left join dep on emp.dep_id = dep.id;
select emp.name, dep.work from dep right join emp on emp.dep_id = dep.id; 2.查询每一个部门下的员工们及员工职责
# select max(dep.name), max(dep.work), group_concat(emp.name) from emp right join dep on emp.dep_id = dep.id group by dep_id; # 分析过程
# 每一个部门 => dep的信息要被全部保留, 需要分组
# 员工职责 => dep.work, 由于分组不能直接被查询 => 需要用聚合函数处理
# 员工们 => emp.name做拼接 => group_concat(emp.name)
# 分组的字段 => 部门 => emp.dep_id => emp.dep_id可以直接被查询,但没有显示意义 => dep.name用来显示 => dep.name需要用聚合函数处理 select max(dep.name), max(dep.work), group_concat(emp.name) from dep left join emp on emp.dep_id = dep.id group by emp.dep_id; # 注: on在where条件关键词之左
'''

练习

二.navicat可视化工具

'''
1. 安装navicat 2.连接数据库,并建库 3.创建表、设置字段、插入数据 4.新建查询
'''

三.python使用mysql(pymysql模块)

# 安装pymysql: pip3 insatll pymysql
# 通过pymysql操作数据库分四步:
'''
1.建立连接
conn = pymysql.connect(host="localhost", port=3306, db='db2', user='root', password='root') 2.设置字典类型游标
cursor = conn.cursor(pymysql.cursors.DictCursor) 3.执行sql语句并使用执行结果 # 书写sql语句
sql = 'select * from emp'
# 执行sql语句, 有返回值, 返回值为得到的记录行数
line = cursor.execute(sql)
print(line) # 使用执行的结果:
fetchone())当前游标往后获取一行记录
fetchall()当前游标往后所有的记录
scroll(num, mode="relative|absolute")
relative: 游标从当前位置往后移动num行
ablolute: 游标从头往后移动num行, 一般可以结合line来使用能定位到任意位置
tag = cursor.fetchone() # 第一条
print(tag)
print(tag['salary'])
tag = cursor.fetchone() # 第二条
print(tag)
cursor.scroll(1, mode='relative') # 偏移第三条
# cursor.scroll(line - 1, mode='absolute') # 指针绝对, 游标永远从头开始偏移
tags = cursor.fetchall() # 第四条到最后
print(tags) 4.断开连接
cursor.close()
conn.close()
'''

四.pymysql处理了sql注入

# 什么是sql注入:
# 通过书写sql包含(注释相关的)特殊字符, 让原有的sql执行顺序发生改变, 从而改变执行得到的sql
# 目的:
# 绕过原有的sql安全认证, 达到对数据库攻击的目的 # 没有处理sql注入的写法
sql = 'select * from user where usr="%s" and pwd="%s"' % (usr, pwd)
res = cursor.execute(sql) # sql注入
# 1.知道用户名: abc" -- hehe | ooo
# select * from user where usr="abc" -- hehe" and pwd="ooo"
# 2.不知道用户名 aaa" or 1=1 -- hehe | 000
# select * from user where usr="aaa" or 1=1 -- hehe" and pwd="000" # 处理sql注入
sql = 'select * from user where usr=%s and pwd=%s'
res = cursor.execute(sql, (usr, pwd))

五.pymysql增删改

# 增
# 增sql语句
sql1 = 'insert into user(usr, pwd) values (%s, %s)'
# 在内存中一次插入一条
cursor.execute(sql1, ("opq", ""))
# 在内存中一次插入多条
cursor.executemany(sql1, [("aaa", ""), ("bbb", "")])
# 将内存中的数据提交到硬盘中
conn.commit() # 删
sql2 = 'delete from user where usr=%s'
cursor.execute(sql2, ("aaa"))
conn.commit() # 改
sql3 = 'update user set pwd=%s where usr=%s'
res = cursor.execute(sql3, ("", "bbb"))
conn.commit()

多表查询、可视化工具、pymysql模块的更多相关文章

  1. MySQL多表查询,Navicat使用,pymysql模块,sql注入问题

    一.多表查询 #建表 create table dep( id int, name varchar(20) ); create table emp( id int primary key auto_i ...

  2. navicat工具 pymysql模块

    目录 一 IDE工具介绍(Navicat) 二 pymysql模块 一 IDE工具介绍(Navicat) 生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具,我们使用Navi ...

  3. 1.多表查询 => 转化为一张联合大表 2.可视化工具 3.pymysql模块

    多表数据 create table dep( id int primary key auto_increment, name varchar(16), work varchar(16) ); crea ...

  4. day43 多表查询和pymysql

    复习 增删改查全语法 # 增 insert into db1.t1(字段2, 字段1, ..., 字段n)|省略 values (值2, 值1, ..., 值n)|(值1, 值2, ..., 值n)[ ...

  5. 不使用left-join等多表关联查询,只用单表查询和Java程序,简便实现“多表查询”效果

    上次我们提到,不使用left-loin关联查询,可能是为了提高效率或者配置缓存,也可以简化一下sql语句的编写.只写单表查询,sql真得太简单了.问题是,查询多个表的数据还是非常需要的. 因此,存在这 ...

  6. python 全栈开发,Day63(子查询,MySQl创建用户和授权,可视化工具Navicat的使用,pymysql模块的使用)

    昨日内容回顾 外键的变种三种关系: 多对一: 左表的多 对右表一 成立 左边的一 对右表多 不成立 foreign key(从表的id) refreences 主表的(id) 多对多 建立第三张表(f ...

  7. 数据库 --- 4 多表查询 ,Navicat工具 , pymysql模块

    一.多表查询 1.笛卡儿积 查询 2.连接 语法: ①inner    显示可构成连接的数据 mysql> select employee.id,employee.name,department ...

  8. day43——多表查询、Navicat工具的使用、pymysql模块

    day43 多表查询 笛卡尔积--不经常用 将两表所有的数据一一对应,生成一张大表 select * from dep,emp; # 两个表拼一起 select * from dep,emp wher ...

  9. 可视化工具Navicat的使用/pymysql模块的使用

    一.可视化工具Navicat的使用 1.官网下载:http://www.navicat.com/en/products/navicat-for-mysql 2.网盘下载:http://pan.baid ...

随机推荐

  1. Python基础之类方法和静态方法

    小叙一会儿: 通常情况下,在类中定义的所有函数(注意了,这里说的就是所有,跟self啥的没关系,self也只是一个再普通不过 的参数而已)都是对象的绑定方法,对象在调用绑定方法时会自动将自己作为参数传 ...

  2. 流媒体服务器SRS部署

    github地址:https://github.com/ossrs/srs 1,srs下载 http://ossrs.net/srs.release/releases/index.html 选择正式发 ...

  3. jenkins 回滚发布

    #jenkins拉取文件路径 workspace=/data/wos/testtemp #备份路径 backspace=/data/wos/back #不能提Git的文件 config=/data/w ...

  4. Python算法之二分查找法

    1: l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88] 从列表中找到某个num的位置 def ...

  5. [转] Lodash常用API笔记

    原生用法 直接使用的API _.reject 根据条件去除某个元素. var foo = [ {id: 0, name: "aaa", age: 33}, {id: 1, name ...

  6. javascript 对象(四)

    一.对象概述 对象中包含一系列的属性,这些属性是无序的.每个属性都有一个字符串key和对应的value. var obj={x:1,y:2}; obj.x; obj.y; 1.为什么属性的key必须是 ...

  7. python之集合set

    1.测试 # python2和python3方法列表相同 ops23 = ['add', 'clear', 'copy', 'difference', 'difference_update', 'di ...

  8. Comparison of several types of convergence

    In functional analysis, several types of convergence are defined, namely, strong convergence for ele ...

  9. eclipse发布后在tomcat下没有文件夹,服务器的Server locations不能修改

    主要是因为Server locations中的deploy路径不正确,要修改这个路径,需要移除服务器中的所有项目,然后点击清空,这时再双击服务器,既可修改这个设置.

  10. js中slice splice substring substr区别

    https://www.jb51.net/article/62165.htm 1.slice(start,end)  #  字符串 2.splice (位置,删除个数,添加元素)# 针对arrary ...