我对我不理解的相关子查询有疑问。 我知道外部表的每一行都运行一个相关的子查询。 例如:
Select departmentID, productid, unit_price
From products a
Where unit_price=(
Select MIN(unit_price)
from products b
Where a.departmentID= b.departmentID
)
Order by a.departmentID
如果它为外部查询中的每一行运行,那么如果外部查询有3行,其中departmentID = 1,则子查询是否为departmentID = 1运行3次,即使它已经计算了MIN(unit_price)一次对于departmentID = 1?。
IMO对于departmentID = 1
多次运行子查询是愚蠢的有人想详细说明吗?
编辑:第二个例子: 外: 选择departmentID,productid,unit_price 来自产品a 其中unit_price = 10且departmentID = 1 内: SELECT MIN(unitprice) 来自Production.Products AS P2 在哪里P2.categoryid = 1
高于相关子查询的工作方式吗?
答案 0 :(得分:3)
首先,如果您对数据库的工作方式有疑问,请使用您正在使用的数据库进行标记。
其次,您的查询是非敏感的,大多数数据库都会拒绝您的查询。您需要对子查询进行比较(例如=
或in
)或exists
。
第三,这种说法不正确:
我知道外部表的每一行都会运行一个相关的子查询。
您应该知道的是,SQL是描述性语言,而不是过程语言。 SQL查询描述了您想要的输出。它不强制要求特定类型的处理。 SQL优化器确定了运行查询的最佳方法。
尽管如此,一些优化者比其他人更聪明。在某些数据库中,相关子查询将始终导致在外部查询中每行运行一次。 (甚至通过正确的索引也可以显着减轻这种行为。)这种行为不是语言的要求;这是这些数据库的限制。
答案 1 :(得分:0)
你误解了。 " ...相关子查询的语句为外表的每一行运行。"不应按字面意思理解。查询处理器,在任何数据库产品中智能地读取和处理优化的查询计划中的数据"在一个或多个抽象级别(比数据更接近)比在任何SQL语言中处理的基于集合的表示更低。 Google" Hash-Joins"," Merge Joins",或"查询优化"了解更多。
该语句仅指出子查询的结果将根据外部结果集的行中的数据而不同,因为它们依赖于该数据,而不相关的子查询,因为它不依赖于外部结果集中的行数据,所以对于每个外部行都是相同的。
答案 2 :(得分:0)
您的查询应该是 -
Select departmentID, productid, unit_price
From products a
Where unit_price = ( -- NOTE - 'unit_price = ' (the condition)
Select MIN(unit_price)
from products b
Where a.departmentID= b.departmentID
)
Order by a.departmentID
如果表products
包含departmentID = 1
的多行,则会在departmentID = 1
的每个时间运行子查询。这是程序性思维方式,在SQL的情况下是错误的,因为SQL是声明性语言。你不应该为每个记录迭代思考。
但请注意,之前的子查询结果不会存储在任何地方。
正如其他人所建议的那样,您不应该以这种方式考虑它,因为 查询规划器 会根据您的查询来处理获取结果的效率。
希望这有帮助。