用Python解释SQL语句执行过程

SQL 语句看上去挺酷,但在数据库内部,它是如何被解释执行的呢?

本文试图用最小的篇幅,解释这个问题.

作者水平有限,内容难免有失偏颇,望请海涵.

首先,一张学生表:

姓名,年龄,班级 = range(3)
张三 = ('张三', 18, '软件一班')
李四 = ('李四', 19, '软件一班')
王五 = ('王五', 19, '软件二班')

学生 = {张三, 李四, 王五}

一张成绩表:

姓名,年龄,班级 = range(3)
张三 = ('张三', 18, '软件一班')
李四 = ('李四', 19, '软件一班')
王五 = ('王五', 19, '软件二班')

学生 = {张三, 李四, 王五}


来一个简单的SQL语句: select  姓名, 年龄, 班级 from 学生 where 姓名 = '张三'

它在数据库里是这样被执行的:

for x in 学生:
    if(x[姓名] == '张三'):
        print(x)

解释一下,上面的代码的含义是: 遍历"学生表"找到"姓名"为"张三"的人,并将它打印出来

作为一个新潮的码农,上面的代码,也可以这样写:

结果 = [ s for s in 学生 if  s[姓名] == '张三']
print("简单查询结果:",结果)

产生的结果,将是这个样子:

简单查询结果: [('张三', 18, '软件一班')]

前奏完毕,现在进入正题

SQL语句

select 学生.姓名, 成绩.学科, 成绩.分数 
from 学生 left join 成绩 on 学生.姓名 = 成绩.姓名 
where 学生.姓名 = '张三'

以上的SQL语句是查询"姓名"为"张三"的同学,在成绩表中的"学科"与"成绩"

语意没问题,但关键是How? 计算机该如何去做?

Step one 来个笛卡尔积.

什么是笛卡尔积?

在数学中,两个集合 X 和 Y 的笛卡儿积(Cartesian product),又称直积,
表示为 X × Y,是其第一个对象是 X 的成员而第二个对象是 Y 的一个成员的所有可能的有序对:
具体的说,如果集合 X 是 13 个元素的点数集合 { A, K, Q, J, 10, 9, 8, 7, 6, 5, 4, 3, 2 } 
而集合 Y 是 4 个元素的花色集合 {♠, ♥, ♦, ♣},
则这两个集合的笛卡儿积是 52 个元素的标准扑克牌的集合
 { (A, ♠), (K, ♠), ..., (2, ♠), (A, ♥), ..., (3, ♣), (2, ♣) }。

版权声明,以上引用自wiki。

解释完毕,首先,我们来一个笛卡尔积:

笛卡尔积 = { (x,y) for x in 学生 for y in 成绩}
print("笛卡尔积结果:",sorted(笛卡尔积))#为了显示美观,特意加了一个排序

它的结果是 酱紫的:

笛卡尔积结果:
 [(('张三', 18, '软件一班'), ('张三', 'C语言', 70)),
(('张三', 18, '软件一班'), ('张三', '数学', 60)), 
(('张三', 18, '软件一班'), ('李四', '数学', 61)), 
(('张三', 18, '软件一班'), ('王五', 'C语言', 63)), 
(('张三', 18, '软件一班'), ('王五', '数学', 62)), 
(('李四', 19, '软件一班'), ('张三', 'C语言', 70)), 
(('李四', 19, '软件一班'), ('张三', '数学', 60)), 
(('李四', 19, '软件一班'), ('李四', '数学', 61)), 
(('李四', 19, '软件一班'), ('王五', 'C语言', 63)), 
(('李四', 19, '软件一班'), ('王五', '数学', 62)), 
(('王五', 19, '软件二班'), ('张三', 'C语言', 70)), 
(('王五', 19, '软件二班'), ('张三', '数学', 60)), 
(('王五', 19, '软件二班'), ('李四', '数学', 61)), 
(('王五', 19, '软件二班'), ('王五', 'C语言', 63)), 
(('王五', 19, '软件二班'), ('王五', '数学', 62))]

数据很多,但绝大多数 没用

接下来,戏法来了,我们在笛卡尔积上加上过滤条件

学生表,成绩表 = range(2)
for x in 笛卡尔积:
    if x[学生表][姓名] == x[成绩表][姓名] and x[学生表][姓名] == '张三':
        print(x)

新潮的写法是:

最终结果= { (x[学生表][姓名], x[成绩表][学科], x[成绩表][分数]) for x in 笛卡尔积 if x[学生表][姓名] == x[成绩表][姓名] and x[学生表][姓名] == '张三'}
print('结果:', 最终结果)

产生的结果是:

结果: 
{('张三', '数学', 60),
 ('张三', 'C语言', 70)}

正如君亲眼所见,数据库软件处理SQL语句有一定的顺序,首先是from语句,然后blah,blah,blah

what's more?

《SQL Server 2005 技术内幕T—SQL查询》

《Inside Microsoft SQL Server 2005:T-SQL Programminy》

抱歉,推荐一本SQL Server的书籍。只看第一章就好。

源代码:

姓名,年龄,班级 = range(3)
张三 = ('张三', 18, '软件一班')
李四 = ('李四', 19, '软件一班')
王五 = ('王五', 19, '软件二班')

学生 = {张三, 李四, 王五}

姓名,学科, 分数 = range(3)
成绩1 = ('张三', '数学', 60)
成绩2 = ('张三', 'C语言', 70)
成绩3 = ('李四', '数学', 61)
成绩4 = ('王五', '数学', 62)
成绩5 = ('王五', 'C语言', 63)

成绩 = {成绩1, 成绩2, 成绩3, 成绩4, 成绩5}

# select  姓名, 年龄, 班级 from 学生 where 姓名 = '张三'

for x in 学生:
    if(x[姓名] == '张三'):
        print(x)
        
结果 = [ s for s in 学生 if  s[姓名] == '张三']
print("简单查询结果:",结果)

#select 学生.姓名, 成绩.学科, 成绩.分数 from 学生 left join 成绩 on 学生.姓名 = 成绩.姓名 where 学生.姓名 = '张三'

#step one,对两个表做笛卡尔积

笛卡尔积 = { (x,y) for x in 学生 for y in 成绩}
print("笛卡尔积结果:",sorted(笛卡尔积))#为了显示美观,特意加了一个排序

学生表,成绩表 = range(2)
#step two,增加过滤条件
最终结果= { (x[学生表][姓名], x[成绩表][学科], x[成绩表][分数]) for x in 笛卡尔积 if x[学生表][姓名] == x[成绩表][姓名] and x[学生表][姓名] == '张三'}
print('结果:', 最终结果)






  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值