关于从(选择...)语句中选择的说明

时间:2018-09-12 05:54:41

标签: sql select

我遇到了一个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子句的内部循环中选择的变量将确定要在外部循环中查询的内容。如开头所述,这次选择是在 对我来说,我很好奇它的功能。它在创建一个假想表吗?

3 个答案:

答案 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 APPLYOUTER APPLY)。该标准将其称为横向衍生表