简体   繁体   English

SQL相关子查询

[英]SQL correlated sub query

I have a question about correlated subqueries that I don't understand. 我有一个我不了解的有关关联子查询的问题。 I know that a correlated subquery runs for each row of the outer table. 我知道外部表的每一行都会运行一个相关的子查询。 Example: 例:

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

If it runs for each row in the outer query, then if the outer query has 3 rows where the departmentID = 1, does the subquery run 3 times for departmentID =1, even though it has calculated the MIN(unit_price) once for departmentID=1?. 如果为外部查询中的每一行运行,则如果外部查询有3行(部门ID = 1),则即使子查询已为DepartmentID ==计算一次MIN(unit_price),子查询是否为DepartmentID = = 1运行3次1?

IMO it would be stupid to run the subquery more than once for departmentID =1 IMO对于部门ID = 1多次运行子查询将是愚蠢的

Anyone care to elaborate? 有人在乎吗?

EDIT: Second example: Outer: Select departmentID, productid, unit_price From products a Where unit_price=10 and departmentID = 1 Inner: SELECT MIN(unitprice) FROM Production.Products AS P2 WHERE P2.categoryid = 1 编辑:第二个示例:外部:从a的产品中选择部门ID,产品ID,单位价格,其中unit_price = 10并且部门ID = 1内部:从Production.Products AS P2 WHERE P2.categoryid = 1中选择MIN(unitprice)。

Is above how the correlated subquery works? 以上是相关子查询的工作方式吗?

First, if you have a question about how databases do things, tag with the database you are using. 首先,如果您对数据库的工作方式有疑问,请使用您正在使用的数据库进行标记。

Second, your query is non-sensical and will be rejected by most databases. 其次,您的查询是无意义的,大多数数据库将拒绝您的查询。 You need either a comparison (such as = or in ) or exists for the subquery. 您需要一个比较(例如=in )或exists于子查询中。

Third, this statement is incorrect: 第三,此语句是不正确的:

I know that a correlated subquery runs for each row of the outer table. 我知道外部表的每一行都会运行一个相关的子查询。

What you should know is that SQL is a descriptive language, not a procedural language. 您应该知道,SQL是一种描述性语言,而不是过程语言。 A SQL query describes the output that you want. SQL查询描述了所需的输出。 It does not mandate a particular type of processing. 它不要求特定类型的处理。 The SQL optimizer determines the best approach for running the query. SQL优化器确定运行查询的最佳方法。

That said, some optimizers are smarter than others. 也就是说,某些优化器比其他优化器更智能。 And in some databases, a correlated subquery will always result in its being run once per row in the outer query. 在某些数据库中,相关子查询将始终导致其在外部查询中每行运行一次。 (And even this behavior is significantly mitigated by proper indexing.) This behavior is not a requirement of the language; (甚至通过适当的索引也大大减轻了这种行为。)这种行为不是语言的要求; it is a limitation of those databases. 这是那些数据库的限制。

You misunderstand. 你误会了。 The statement that "...correlated subquery runs for each row of the outer table." 语句“ ...相关子查询针对外部表的每一行运行”。 is not to be taken literally. 不能从字面上看。 The query processor, in any database product intelligently reads and processes the data in an optimized "query plan" that is at one or more levels of abstraction lower (closer to the data) than the set-based representation you deal with in any SQL-language. 在任何数据库产品中,查询处理器都会智能地读取和处理经过优化的“查询计划”中的数据,该“查询计划”的抽象级别比您在任何SQL-语言。 Google "Hash-Joins", "Merge Joins", or "query Optimization" to learn more. Google的“哈希联接”,“合并联接”或“查询优化”以了解更多信息。

The statement is only making the point that the results of the sub-query will be different based on the data in the row of the outer resultset, because they are dependent on that data, whereas an un-correlated sub-query, because it is not dependent on the row data in the outer resultset, will be the same for every outer row. 该语句只是指出,子查询的结果将基于外部结果集的行中的数据而有所不同,因为它们依赖于该数据,而不相关的子查询则是因为它依赖于该数据。不依赖于外部结果集中的行数据,每个外部行都将相同。

Your Query should be - 您的查询应该是-

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

Here if the table products contains more than one rows for departmentID = 1 then sub-query is run for each of the time when departmentID = 1 . 在这里,如果表products包含多于一行的departmentID = 1行,那么当departmentID = 1时,每次都会运行子查询。 This is procedural way of thinking and is wrong in case of SQL because SQL is a declarative language. 这是一种过程性的思维方式,在SQL的情况下是错误的,因为SQL是一种声明性语言。 You should not think iteratively for each records. 您不应该为每条记录反复考虑。

However, note that the previous sub queries results are not stored anywhere. 但是,请注意,先前的子查询结果不会存储在任何地方。

As others suggested you should not think of the it this way, as Query Planner takes care of how efficiently the results could be fetched based on your query. 正如其他人建议的那样,您不应该这样想,因为Query Planner负责根据查询查询结果的效率。

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM