我遇到了一个SQL实践问题。答案是
SELECT ROUND(ABS(a - c) + ABS(b - d), 4) FROM (
SELECT MIN(lat_n) AS a, MIN(long_w) AS b, MAX(lat_n) AS c, MAX(long_w) AS d
FROM station);
通常,我会成为
select[] from[] where [] (select...)
表示从where子句的内部循环中选择的变量将确定要在外部循环中查询的内容。如开头所述,这次选择是在 从对我来说,我很好奇它的功能。它在创建一个假想表吗?
答案 0 :(得分:3)
括号中的部分:
(SELECT MIN(lat_n) AS a, MIN(long_w) AS b, MAX(lat_n) AS c, MAX(long_w) AS d FROM station)
是子查询。
这里重要的是,子查询的结果看起来像是外部查询的常规表。在某些SQL风格中,必须在右括号后紧跟一个别名(即,用于引用表状结果的名称)。
从技术上讲这是否是“临时表”有点细节,因为其结果不会存储在查询范围之外;还有一个叫做 的临时表。
另外(这可能是造成混乱的原因),子查询也可以在WHERE
子句中与运算符(例如IN
)一起使用,如下所示:< / p>
SELECT student_name
FROM students
WHERE student_school IN (SEELCT school_name FROM schools WHERE location='Springfield')
答案 1 :(得分:2)
这是注释和other answer子查询中讨论的内容。
从逻辑上讲,这样的子查询(当它出现在FROM
子句中)首先执行,然后将结果视为表 1 。但是重要的是,SQL语言 2 不需要 。整个查询(包括所有子查询)都进行了优化。
这可以包括优化程序执行的操作,例如从外部WHERE
子句(当然,您的查询中没有一个子句)将谓词下推到子查询(如果是)最好早于而不是晚地评估该谓词。
类似地,如果您的查询中有两个子查询都访问同一基表,那么 not 不一定意味着数据库系统将实际上查询该基表正好两次。
无论如何,数据库系统是否选择物化结果(将结果存储在某个地方)也要在优化阶段确定。因此,在不知道您确切的RDBMS以及优化器为优化此特定查询所采取的决策的情况下,无法说出它是否会真正存储某些内容。
1 请注意,子查询生成的“表的结果集”没有标准术语。有人提到过“临时表”,但是由于这是SQL中具有 specific 含义的术语,因此在此不再使用。我通常使用术语“结果集”来描述由列和行组成的任何数据集。这既可以用来描述整个查询的结果,也可以用来描述查询中较小的部分。
2 提供的最终结果与“好像”以其逻辑处理顺序执行了查询一样,实现可以自由选择以其选择的任何顺序执行处理。
答案 2 :(得分:0)
由于涉及的术语太多,我只是想再提一个答案...
在关系数据库中,我们处理表。查询从表中读取,其结果再次是表(尽管不是存储的表)。
因此,在FROM
子句中,我们可以像访问任何存储表一样访问查询结果:
select * from (select * from t) x;
这使内部查询成为我们主查询的子查询。我们也可以将其称为临时视图,因为视图是我们用于访问数据的查询的词。我们可以将其移至主查询的开头,以增强可读性,并可能在其中多次使用:
with x as (select * from t) select * from x;
我们甚至可以存储此类查询供以后访问:
create view v as select * from t;
select * from v;
在SQL标准中,使用了以下术语:
CREATE TABLE ...
创建的存储表。以上示例中的t
应该是基本表。CREATE VIEW ...
创建的视图。以上示例中的v
是一个查看表。x
。在FROM
以外的其他子句中使用子查询时(例如,在SELECT
子句或WHERE
子句中),我们不使用术语“派生表”。这是因为在这些子句中,我们不访问表(即不存在类似WHERE mytable = ...
的表),而是访问列和表达式的结果。因此,术语“子查询”比术语“派生表”更笼统。但是,在那些子句中,我们仍然对子查询使用各种术语。有相关和不相关的子查询以及标量和非标量子查询。
为了使事情变得更加复杂,我们可以在现代DBMS的FROM
子句中使用相关的子查询,这些子查询具有横向联接(有时实现为CROSS APPLY
和OUTER APPLY
)。该标准将其称为横向衍生表。