10.10 多表连接查询

10.101 内连接

把两张表有对应关系的记录连接成一张虚拟表

select * from emp,dep;                                  #连接两张表的笛卡尔积
select * from emp,dep where emp.dep_id = dep.id; # 不推荐用where连接表
select * from emp inner join dep on emp.dep_id = dep.id; #推荐
+----+-----------+--------+------+--------+------+--------------+
| id | name | sex | age | dep_id | id | name |
+----+-----------+--------+------+--------+------+--------------+
| 1 | egon | male | 18 | 200 | 200 | 技术 |
| 2 | alex | female | 48 | 201 | 201 | 人力资源 |
| 3 | wupeiqi | male | 38 | 201 | 201 | 人力资源 |
| 4 | yuanhao | female | 28 | 202 | 202 | 销售 |
| 5 | liwenzhou | male | 18 | 200 | 200 | 技术 |
+----+-----------+--------+------+--------+------+--------------+
#应用:
select * from emp,dep where emp.dep_id = dep.id and dep.name = "技术";
select * from emp inner join dep on emp.dep_id = dep.id where dep.name = "技术";
+----+-----------+------+------+--------+------+--------+
| id | name | sex | age | dep_id | id | name |
+----+-----------+------+------+--------+------+--------+
| 1 | egon | male | 18 | 200 | 200 | 技术 |
| 5 | liwenzhou | male | 18 | 200 | 200 | 技术 |
+----+-----------+------+------+--------+------+--------+

应用

10.102 左连接

在内连接的基础上,保留左边没有对应关系的记录

select * from emp left join dep on emp.dep_id = dep.id;
+----+------------+--------+------+--------+------+--------------+
| id | name | sex | age | dep_id | id | name |
+----+------------+--------+------+--------+------+--------------+
| 1 | egon | male | 18 | 200 | 200 | 技术 |
| 5 | liwenzhou | male | 18 | 200 | 200 | 技术 |
| 2 | alex | female | 48 | 201 | 201 | 人力资源 |
| 3 | wupeiqi | male | 38 | 201 | 201 | 人力资源 |
| 4 | yuanhao | female | 28 | 202 | 202 | 销售 |
| 6 | jingliyang | female | 18 | 204 | NULL | NULL |
+----+------------+--------+------+--------+------+--------------+

10.103 右连接

在内连接的基础上,保留右边没有对应关系的记录

select * from emp right join dep on emp.dep_id = dep.id;
+------+-----------+--------+------+--------+------+--------------+
| id | name | sex | age | dep_id | id | name |
+------+-----------+--------+------+--------+------+--------------+
| 1 | egon | male | 18 | 200 | 200 | 技术 |
| 2 | alex | female | 48 | 201 | 201 | 人力资源 |
| 3 | wupeiqi | male | 38 | 201 | 201 | 人力资源 |
| 4 | yuanhao | female | 28 | 202 | 202 | 销售 |
| 5 | liwenzhou | male | 18 | 200 | 200 | 技术 |
| NULL | NULL | NULL | NULL | NULL | 203 | 运营 |
+------+-----------+--------+------+--------+------+--------------+

10.104 全连接

在内连接的基础上,保留左、右边没有对应关系的记录,并去重

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 | sex | age | dep_id | id | name |
+------+------------+--------+------+--------+------+--------------+
| 1 | egon | male | 18 | 200 | 200 | 技术 |
| 5 | liwenzhou | male | 18 | 200 | 200 | 技术 |
| 2 | alex | female | 48 | 201 | 201 | 人力资源 |
| 3 | wupeiqi | male | 38 | 201 | 201 | 人力资源 |
| 4 | yuanhao | female | 28 | 202 | 202 | 销售 |
| 6 | jingliyang | female | 18 | 204 | NULL | NULL |
| NULL | NULL | NULL | NULL | NULL | 203 | 运营 |
+------+------------+--------+------+--------+------+--------------+

补充:多表连接可以不断地与虚拟表连接

#查找各部门最高工资
select t1.* from emp as t1 inner join (select post,max(salary) as ms from emp group by post) as t2
on t1.post = t2.post
where t1.salary = t2.ms;

10.11 子查询

把一个查询语句用括号括起来,当做另外一条查询语句的条件去用,称为子查询

#查询技术部员工的名字
select emp.name from emp inner join dep on emp.dep_id = dep.id where dep.name="技术";#连接查询
select name from emp where dep_id =(select id from dep where name="技术"); #子查询
+-----------+
| name |
+-----------+
| egon |
| liwenzhou |
+-----------+
#查询平均年龄在25岁以上的部门名 #子查询
select name from dep where id in (select dep_id from emp group by dep_id having avg(age) > 25);
select dep.name from emp inner join dep on emp.dep_id = dep.id #连接查询
group by dep.name
having avg(age) > 25;
+--------------+
| name |
+--------------+
| 人力资源 |
| 销售 |
+--------------+
#查询每个部门最新入职的那位员工
select t1.id,t1.name,t1.post,t1.hire_date,t2.post,t2.max_date from (emp as t1) inner join
(select post,max(hire_date) as max_date from emp group by post) as t2 #拿到最大雇佣时间
on t1.post = t2.post
where t1.hire_date = t2.max_date;
+----+--------+-----------------------------------------+----
| id | name | post | hire_date | post | max_date |
+----+--------+-----------------------------------------+-----
| 1 | egon | 外交大使 | 2017-03-01 | 外交大使 | 2017-03-01 |
| 2 | alex | teacher | 2015-03-02 | teacher | 2015-03-02 |
| 13 | 格格 | sale | 2017-01-27 | sale | 2017-01-27 |
| 14 | 张野 | operation| 2016-03-11 | operation| 2016-03-11 |
+----+--------+-----------------------------------------+-----

exists( ):括号内的值存在时满足条件

select * from emp where exists (select id from dep where id > 3);       #找到所有

10.12 pymysql模块的使用

10.121 pymysql查

import pymysql              #pip3 install pymysql
conn=pymysql.connect( #连接
host='127.0.0.1',
port=3306,
user='root',
password='',
database='db2',
charset='utf8')
cursor=conn.cursor(pymysql.cursors.DictCursor)#以字典形式显示表的记录
rows=cursor.execute('show tables;') #1 显示受影响的行数(row),此处为有表的条数
print(rows)
rows=cursor.execute('select * from emp;') #18 此处rows为emp表内有记录的条数
print(rows)
​
print(cursor.fetchone()) #查看一条记录 一个字典{key:value}
print(cursor.fetchmany(2)) #查看多条记录 [{key:value},]
#print(cursor.fetchall()) #查看所有记录 强调:下一次查找是接着上一次查找的位置继续
​
cursor.scroll(0,'absolute') #绝对移动,以0位置为参照显示
print(cursor.fetchone())
​
cursor.scroll(1,'relative') #相对移动,相对当前位置移动1条记录
print(cursor.fetchone())
​
cursor.close()#光标
conn.close()

10.122 防止sql注入问题

在服务端防止sql注入问题:不要自己拼接字符串,让pymysql模块去拼接,pymysql拼接时会过滤非法字符

import pymysql
conn=pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='',
database='db2',
charset='utf8'
)
cursor=conn.cursor(pymysql.cursors.DictCursor)
​
inp_user=input('用户名>>:').strip() #inp_user=""
inp_pwd=input('密码>>:').strip() #inp_pwd=""
sql="select * from user where username=%s and password=%s"
print(sql) rows=cursor.execute(sql,(inp_user,inp_pwd))#输入的用户名和密码中的非法字符会被过滤掉
if rows:
print('登录成功')
else:
print('登录失败')
cursor.close()
conn.close()

10.123 pymysql增删改

import pymysql
conn=pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='',
database='db2',
charset='utf8')
cursor=conn.cursor(pymysql.cursors.DictCursor)
sql='insert into user(username,password) values(%s,%s)' #插入单行记录
rows=cursor.execute(sql,('EGON',''))
print(rows)
print(cursor.lastrowid) #显示当前最后一行的id
​
sql='insert into user(username,password) values(%s,%s)' #一次插入多行记录
rows=cursor.executemany(sql,[('lwz','123'),('evia','455'),('lsd','333')])
print(rows)
​
rows=cursor.execute('update user set username="alexSB" where id=2')#修改记录
print(rows)
​
conn.commit() # 只有commit提交才会完成真正的修改
cursor.close()
conn.close()

python 之 数据库(多表查询之连接查询、子查询、pymysql模块的使用)的更多相关文章

  1. MySQL数据库学习笔记(六)----MySQL多表查询之外键、表连接、子查询、索引

    本章主要内容: 一.外键 二.表连接 三.子查询 四.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复 ...

  2. MySQL数据库学习笔记----MySQL多表查询之外键、表连接、子查询、索引

    本章主要内容: 一.外键 二.表连接 三.子查询 四.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复 ...

  3. MS sql server 基础知识回顾(二)-表连接和子查询

    五.表连接 当数据表中存在许多重复的冗余信息时,就要考虑将这些信息建在另一张新表中,在新表中为原表设置好外键,在进行数据查询的时候,就要使用到连接了,表连接就好像两根线,线的两端分别连接两张表的不同字 ...

  4. MySQL多表查询之外键、表连接、子查询、索引

    MySQL多表查询之外键.表连接.子查询.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为 ...

  5. mysql学习笔记-- 多表查询之外键、表连接、子查询、索引

    本章主要内容: 一.外键 二.表连接 三.子查询 四.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复 ...

  6. 数据库——SQL-SERVER练习(1)连接与子查询

    一.实验准备 1.复制实验要求文件及“CREATE-TABLES.SQL”文件, 粘贴到本地机桌面. 2.启动SQL-SERVER服务. 3. 运行查询分析器, 点击菜单<文件>/< ...

  7. mysql表查询、多表查询(增强查询的使用)子查询、合并查询,外连接,mysql5种约束,自增长

    一.查询加强 1.在mysql中,日期类型可以直接比较,需要注意格式 2.%:表示0到多个字符, _:表示单个字符 exp:显示第二个字符为大写O的所有员工的姓名和工资 select  name fr ...

  8. ylb:SQL 表的高级查询-多表连接和子查询

    ylbtech-SQL Server: SQL Server-表的高级查询-多表连接和子查询 SQL Server 表的高级查询-多表连接和子查询. 1,ylb:表的高级查询-多表连接和子查询 返回顶 ...

  9. oracle之复杂查询(下):子查询

    复杂查询(下):子查询 8. 1 非关联子查询:返回的值可以被外部查询使用.子查询可以独立执行的(且仅执行一次). 8.1.1 单行单列子查询,子查询仅返回一个值,也称为标量子查询,采用单行比较运算符 ...

  10. mysql加强(6)~子查询简单介绍、子查询分类

    一.子查询简单介绍 1.什么是子查询? 一个查询之中嵌套了其他的若干查询. 在使用select 语句查询时,有时候where的查询条件中的限制条件不是一个确定的值,而是一个来自于另一个查询的结果. 子 ...

随机推荐

  1. CAS5.3服务环境搭建

    什么是Overlay overlay可以把多个项目war合并成为一个项目,并且如果项目存在同名文件,那么主项目中的文件将覆盖掉其他项目的同名文件.使用maven 的Overlay配置实现无侵入的改造c ...

  2. Android根据内网外网连接情况配置服务器访问IP

    新项目的app,可通过内网和外网的服务器ip进行请求访问,但是客户提供了专业终端,终端在wifi情况下走外网内网都可以,但关闭wifi则只能走4G专网,也就是只能走内网. 可前往我的小站查看:Andr ...

  3. Oracle表空间 与 分页

    目录 Oracle表空间 表空间的构建以及数据文件的挂接 创建一个用户,并指定专有的永久表空间和临时表空间 伪列 分页 Oracle表空间 一个表空间可以包含1至n个数据文件 一个数据文件必然属于某个 ...

  4. fdconnection自动重连

    fdconnection自动重连 1)设置 FDConnection1.ResourceOptions.AutoReconnect := True; 控制自动连接的恢复. 使用AutoReconnec ...

  5. MySQL - \g 和 \G用法与区别

    [1]DOS环境下 ① \g 可同时(单独)使用\g; 其作用等效于分号—’:’ : ② \G 可同时(单独)使用\G;; /G 的作用是将查到的结构旋转90度变成纵向:

  6. 修改layui的表单手机、邮箱验证可以为空怎么实现?

      修改layui的表单手机.邮箱验证可以为空   解决办法: 修改源码: 把表单验证源代码(form.js)的正则表达式改一下,例如手机的正则为:/^1d{10}$/,可以改成/^$|^1d{10} ...

  7. Robot Framework安装使用

    关于robotframework环境搭建安装请参考 另外一篇博文:Robot Framework的环境搭建(就是一些库文件的安装) 项目基本流程: 1.创建项目New Project----选择dir ...

  8. 【JDBC】仅输入表名和要插入的记录数,自动检测表的字段和类型,然后插入数据的全自动程序(Oracle版)

    之前写的批量插值程序只是五六半自动版本,因为表的字段还需要手工填写,这回只要指定表名和要插多少数据就行了,类似于全自动突击步枪,扣动扳机就把字段打完为止. 全自动程序如下,诸位拿下去后可以修改成自己想 ...

  9. return语句——学习笔记

    return,可以提前结束其所在函数. 函数内不写,会自动加上return. 非引用返回: 引用返回:a=3,b=3 注意事项: 两种修改字符串某一位置值的方式:

  10. shell编程系列8--文本处理三剑客之grep和egrep

    grep和egrep 第一种形式:grep [option] [pattern] [file1,file2...] 第二种形式:command | grep [option] [pattern] gr ...