文章

sql优化 09-18-2023

在学习CS50的时候,遇到了一些可以优化的sql语法结构,特此记录下来。

在做cs50的时候,sql最后一个作业讲述的是有个人的鸭子被偷了。

这个作业本身也是特别有意思,做这个作业,就像玩游戏一样。

甚至在reddits上看到不少人都发帖问,有没有和这种题目类似的sql题目,看来大家都很喜欢这题目。

在做的时候,我遇到了下面的一些sql问题,特地记录下来

例如下面这段语法,目的是查找指定的人通话过的另一个人的信息,里面使用到了嵌套语句,语法看起来没有那么好读懂

首先这三个table的关系是phone_calls和people通过phone_number互相连接的,phone_calls表里面有和caller和receiver

要在已知caller的名字前提下,或者receiver的信息

下面是嵌套语法

1
2
3
4
5
6
7
8
SELECT * FROM people
WHERE people.phone_number IN(
SELECT phone_calls.receiver FROM phone_calls
JOIN people ON people.phone_number = phone_calls.caller
WHERE people.name = 'person_name'
AND phone_calls.day = '28'
AND phone_calls.duration < '60'
);

如果出现多层嵌套的话,会加大sql查询的复杂性

下面是经过优化后的语法

1
2
3
4
5
6
7
SELECT DISTINCT p_receiver.name FROM phone_calls
JOIN people p_caller ON pc.caller = p_caller.phone_number
JOIN people p_receiver ON pc.receiver = p_receiver.phone_number
WHERE p_caller.name = 'person_name'
AND pc.day = 28
AND pc.duration < 60;

这个查询连接了 phone_calls 表与 people 表两次

一次用于获取打电话的人员名字 (p_caller)

另一次用于获取接收电话的人员名字 (p_receiver)。

然后,根据打电话者的名字筛选满足条件的通话记录,返回接收者的名字。

也就是将表 people 获取了两次,获得了两个子表,两个子表分别和 phone_calls 进行了连接。

一个子表是用来对caller的名字进行查找

另一个用来获得我所需要的receiver

本文由作者按照 CC BY 4.0 进行授权