用Python解释SQL语句执行过程

来源:互联网 发布:数据恢复后照片无预览 编辑:程序博客网 时间:2024/06/05 21:05

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('结果:', 最终结果)




原创粉丝点击