这是数据库的架构:
Suppliers(sid:integer, sname:string, address:string)
Parts(pid:integer,pname:string,color:string)
Catalog(sid:integer,pid:integer,cost:real)
目标:对于每个部分,找到对该部分收费最高的供应商的sname。
教授的代码:
SELECT P.pid, S.sname
FROM Parts P, Suppliers S, Catalog C
WHERE C.pid = P.pid AND C.sid = S.sid
AND C.cost = (SELECT MAX (C1.cost)
FROM Catalog C1
WHERE C1.pid = P.pid)
现在,一般来说,我对SQL很新,所以我一直在努力尝试从概念上理解查询的工作原理。看看上面的查询,我很困惑子查询是如何工作的。我知道子查询是否只是
SELECT MAX (C1.cost)
FROM Catalog C1
它只会返回Catalog表中的最大成本。但这有条件WHERE C1.pid = P.pid
,这是我的思想停止工作的地方。我们想要每个部分的最高成本。从概念上讲,SQL查询如何知道单独查看每个pid? WHERE子句的添加是否使得所有类似于循环(使用常规编程语言)?这意味着它将在pid列表中找到,找到每个pid的最大成本并返回它以与C.cost进行比较,然后转到下一个pid?或者这一切究竟是如何在概念上发生的? (在我的脑海中,有些东西在精神上缺失,这有助于我理解它是如何通过每个id来理解的)
我最近一直在问一些关于SQL的非常模糊的问题,因为出于某些原因,我正在努力寻找...与其他编程语言相比,真正理解其中一些基础的好资源,而我继续让人们投票来结束我的问题,但是如果有人能够至少告诉我如何更好地说出我的问题或指导我更好地理解这一点,我将非常感激。
答案 0 :(得分:2)
我的第一个建议是不要试着将SQL看作是一种编程语言。如果你开始考虑循环(可能是递归的sql之外)或if语句(在Case语句之外),你将最终处于一个不好的地方。而是考虑数据集。 “这部分查询获取了这组数据”。 SQL是一种创建和处理数据集的语言。
对于此查询,您可以使用英语:“向我提供产品的PID
和SNAME
及其最高cost
。此外,产品必须在产品中,目录和供应商表。“
这里假设您的Catalog
表每个产品可能有多个条目,costs
可能在这些条目之间有所不同。因此,我们使用相关子查询来确定那些costs
中哪一个最高。
我添加了但是关于需要在所有三个表中的产品,只是指出这是使用隐式的INNER JOIN。我不是那个隐含部分的忠实粉丝,并且总是喜欢人们在查询的FROM
部分写出“INNER JOIN ON ...”。隐含的INNER JOIN更老派。
回过头来考虑数据集。想象一下,我们加入所有三个表并返回所有字段。从概念上讲,每个产品可能在结果集中具有多个记录,并且具有不同的成本以区分一个记录与下一个记录。因此,我们添加子查询和约束,即记录集中的成本需要是目录中特定产品(子查询WHERE子句)可以找到的最高成本。
答案 1 :(得分:1)
这里有correlated subquery。对于主查询中的每一行,子查询都将被执行,这就是子查询可以引用主查询的原因。