FROM, including JOINs
WHERE
GROUP BY
HAVING
WINDOW functions
SELECT
DISTINCT
UNION
ORDER BY
LIMIT and OFFSET
FROM, including JOINs
将首先评估FROM子句中指定的表(包括JOIN),以确定与查询相关的整个工作集。数据库将根据JOINs ON子句合并所有表中的数据,同时还从子查询中获取数据,甚至可能会创建一些临时表来保存此子句中从子查询返回的数据。
但是,在许多情况下,数据库的优化器会选择首先评估WHERE部分,以查看可以忽略工作集的哪一部分(最好使用索引),因此,如果不这样做,则不会过度膨胀数据集。真的不是必须的。
WHERE
在FROM子句之后,WHERE子句将是第二个要评估的子句。我们已经准备好了工作数据集,现在我们可以根据WHERE子句中的条件过滤数据了。
这些条件可以包括对FROM子句中的数据和表的引用,但不能包括对SELECT子句中定义的别名的任何引用,因为该数据和那些别名可能尚未在该上下文中“存在”,因为该子句不存在。尚未由数据库评估。
另外,WHERE子句的一个常见陷阱是尝试过滤掉WHERE子句中的聚合值,例如,使用以下子句:“ WHERE sum(available_stock)> 0 ”。该语句将使查询执行失败,因为聚合将在该过程的稍后阶段进行评估(请参阅下面的GROUP BY部分)。若要对聚合数据应用筛选条件,应使用HAVING子句而不是WHERE子句。
GROUP BY
现在,我们使用WHERE子句过滤了数据集,我们可以根据GROUP BY子句中出现的一列或多列来汇总数据。对数据进行分组实际上是将其拆分为不同的块或存储桶,其中每个存储桶都有一个键和与该键匹配的行的列表。没有GROUP BY子句就像将所有行放在一个大的存储桶中。
汇总数据后,您现在可以使用汇总函数为每个存储桶返回每个组的值。这样的聚合函数包括COUNT,MIN,MAX,SUM等。
HAVING
现在,我们已经使用GROUP BY子句对数据进行了分组,现在可以使用HAVING子句过滤掉一些存储桶了。HAVING子句中的条件可以引用聚合函数,因此上面的WHERE子句中不起作用的示例将在HAVING子句中正常工作:“ HAVING sum(available_stock)> 0”。
由于我们已经对数据进行了分组,因此我们现在无法再访问原始行,因此我们只能应用条件来过滤整个存储桶,而不能应用存储桶中的单行。
WINDOW functions
如果您使用的是WINDOW functions
,那么这就是执行它们的地方。就像分组机制一样,Window函数也在一组行上执行计算。主要区别在于,在使用Window函数时,每一行将保留自己的标识,并且不会被分组到其他类似行的存储桶中。
WINDOW functions
只能在SELECT或ORDER BY子句中使用。您可以在Window函数内部使用聚合函数
SELECT
DISTINCT
关键字的语法有点令人困惑,因为该关键字在SELECT子句中的列名称之前位于其位置。但是,实际的DISTINCT操作发生在SELECT之后。使用DISTINCT关键字时,数据库将在进行过滤和聚合后从剩余的剩余行中丢弃具有重复值的行。
UNION
UNION关键字将两个查询的结果集组合为一个结果集。大多数数据库将允许您在UNION DISTINCT(将从组合结果集中丢弃重复的行)或UNION ALL(仅合并结果集而不应用任何重复检查)之间进行选择。
您可以对UNION的结果集应用排序(ORDER BY)和限制(LIMIT),就像将其应用于常规查询一样。
ORDER BY
一旦数据库准备好整个结果集(在过滤,分组,删除重复项之后),便会进行排序。一旦有了这些,数据库现在就可以使用列,选定的别名或聚合函数对结果集进行排序,即使它们不是选定数据的一部分。唯一的例外是使用DISTINCT关键字时,它防止按未选择的列进行排序,因为在这种情况下,结果集的顺序将是不确定的。
您可以选择使用降序(DESC)或升序(ASC)排序数据。该订单对于每个订单零件都可以是唯一的,因此以下内容有效:ORDER BY名字ASC,年龄DESC