购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.2.5 使用小括号改变连接对象

本节我们将一起解决前面留给大家的问题。

相信同学们还记得,前面说过,一个过滤条件其实就是一个限定词。题干中一共出现了3个限定词,分别是罗蒙水产、约瑟夫种植园和巴尔干甜豆。这样一来,我们就可以草拟出相对应的3个过滤要求:supplier='罗蒙水产'、supplier='约瑟夫种植园'和name='巴尔干甜豆'。

好了,现在摆在我们面前的问题其实很简单,那就是使用AND和OR来协调这3个过滤要求之间的逻辑关系。换句话来讲,我们需要将AND和OR插入它们中间,此处一共有4种不同的编排方式:

虽然编排方式不少,但我们其实可以快速地将1、3给排除掉。原因很简单,因为操作符AND协调的过滤机制是同时满足,所以supplier='罗蒙水产'AND supplier='约瑟夫种植园'表示要求MySQL从supplier列中找到名称既是“罗蒙水产”又是“约瑟夫种植园”的供应商。毫无疑问,这样一位供应商在Spice表中并不存在,所以1、3两种编排方式会被去掉。

接着,我们再来看看编排方式2。由于操作符OR协调的过滤机制是分别满足,所以MySQL会让这3个过滤要求独立开展:

然后汇总显示它们的过滤结果。当然,MySQL会事先去掉重复行,因此最终结果含有的信息包括由罗蒙水产提供的所有品类、由约瑟夫种植园提供的所有品类,以及所有的巴尔干甜豆。这很明显与我们的需求不符,因此,我们就只剩最后一种编排方式了:

事实上,如果同学们的答案和这条SQL语句一样,那么你离成功其实就只差一步了。现在我们一起来看看这条语句执行后的返回结果:

哦?第二行和第五行信息出了问题,因为我们的目标只有巴尔干甜豆,但这里却返回了雪松木和香草荚,看来MySQL并没有通过这条语句读懂我们的需求。不过我们已经没有其他选择了,那么问题到底出在哪里了呢?

我们此前说过这样一句话:其实学习SQL,就是学着用它来表达我们的需求。而这大致会产生以下3种情形。

· 如果使用了与需求相匹配的SQL语句,那么MySQL就会返回我们期待的结果。

· 如果写下的SQL语句存在语法或拼写错误,那么MySQL就不会执行,或者报错。这将不会有任何结果返回。

· 如果写下的SQL语句本身没有问题,但我们没有表述到位,那么即使语句被顺利执行,MySQL也不会给我们想要的结果。

事实上,我们此处遇到的情况就属于最后一种情形。筛选结果中出现了本不应该被返回的行,这就表明没有过滤透彻,所以问题很可能出在了WHERE从句上。下面我们单独把WHERE从句提取出来,然后给各个过滤要求加上编号:

接着,我们再来听听MagicSQL是如何理解这句话的。

说实在的,一年级新生,你这么写我可看不太明白。你瞧,对于OR来讲,它连接的前段肯定是①,但是它连接的后段究竟是单独的②,还是②AND③?同样的道理,AND连接的后段肯定是③,可是看样子它的前段既可以是单独的②,也可以是整个①OR②。

看到了吗,正是因为我们表述不严谨,MySQL才产生了混淆。不过MySQL并没有因此报错,还是返回了一些信息。这又是为什么呢?

虽然我不爱多管闲事,但这句话却给了我发挥想象的空间。事实上,在这种指向不明的情况下,我会做出自己的选择:将“②AND③”合并为一个整体,然后将它们共同当作OR连接的后段。

没错,正是如此!AND具有优先选择权,也就是说,当AND和OR同时出现时,MySQL会先让AND选择它连接的前后部分,再与OR进行合并。不过这样一来,MySQL就把我们的需求误读成了“找到由约瑟夫种植园提供的巴尔干甜豆,以及由罗蒙水产提供的所有品类”。这明显与我们的实际需求不符,所以我们要使用小括号来改变AND的连接对象,就像这样:

瞧,小括号将“罗蒙水产”与“约瑟夫种植园”合并成了一个整体,然后将这个整体当作AND连接的前段。这条语句正好对应我们的需求——找到由“罗蒙水产”和“约瑟夫种植园”提供的“巴尔干甜豆”。

不过例句(5)并非唯一的解决方案。事实上,我们还可以对它进行改编。改编的思路源于一个看似毫不相干的定律,就是乘法分配律:

现在请大家将“+”视为“OR”,将“*”视为“AND”。那么例句(5)将进一步被展开为:

大家可以试着解读,例句(6)对应的需求是:找到由“罗蒙水产”提供的“巴尔干甜豆”,以及由“约瑟夫种植园”提供的“巴尔干甜豆”。这其实与我们的目标相一致,只是换了一种表达方式而已!

好了,亲爱的同学们,想必大家一定很想知道李乔丹昨天的约会如何,其实我和你们一样好奇。

唉,我正想找你们聊聊呢。昨天在见到Grace以后,我想她可能只有戴上面具才像苏菲·玛索。不过我并不是“外貌协会”,这一点你们是知道的。但无论怎样,Grace并不是真正让我心动的女孩。

看来李乔丹的约会之路并不顺利,不过他用不着气馁,因为精彩的故事往往不会有一帆风顺的开头。要知道,生活一般不会立即给你迫切想要的结果,它会安静地躲在一旁考验你的耐心。只要你心存美好,不轻易放弃,生活就会以意想不到的方式给你惊喜。如果你要问我什么样的美好最值得珍藏,我的回答是,不期而遇的美好最值得珍藏!

听你这么一说,我感觉好多了!事实上,昨晚我认真考虑了一下,根据我的生活轨迹来看,我应该尝试多接触居住在洛杉矶和波士顿的女孩。当然,年龄相仿的会有更多的共同话题。

瞧,李乔丹提出了新的交友思路。现在就请大家帮帮他,试着用SQL语言来表达以下需求。

1. 请找到年龄在30岁以下,且来自洛杉矶的女孩。

2. 请分别找到来自洛杉矶和波士顿的女孩。

3. 请找到年龄在30岁以下,且分别居住在洛杉矶和波士顿的女孩。

先来看看需求1,“年龄在30岁以下”且“来自洛杉矶”对应两个过滤要求“age<30”和“location='洛杉矶'”。为了同时满足这两个过滤要求,我们就要使用AND来协调它们之间的逻辑关系:

需求2要求分别找到来自“洛杉矶”和“波士顿”的女孩。那么毫无疑问,为了分别满足“来自洛杉矶”和“来自波士顿”这两个过滤要求,我们会使用OR来协调它们之间的逻辑关系:

需求3的要求稍微复杂一些,因为它涉及3个过滤要求“年龄在30岁以下”、“来自洛杉矶”和“来自波士顿”。为了准确无误地表达需求,我们将同时使用AND和OR,并搭配小括号:

当然,别出心裁的改编形式总会受到欢迎: 1zBXlk7n0Wgl+nLklKHV1K0SGv7c0ODq1DijK8K2lrLz+RIyaWFS2LyGu8iilnKQ

点击中间区域
呼出菜单
上一章
目录
下一章
×

打开