MSSQL执行顺序解析:一步步了解!

介绍

Microsoft SQL Server(MSSQL)是Microsoft开发的一种关系数据库管理系统。在将SQL语句发送到服务器以执行操作时,MSSQL数据库的执行顺序非常重要。本文旨在介绍MSSQL查询的执行顺序。

执行顺序概述

执行MSSQL查询时,数据库引擎会按照特定顺序对查询的各个部分进行处理。这个顺序称为查询的执行顺序,也称为查询的处理顺序。以下是MSSQL查询操作的常用执行顺序。

FROM

ON

JOIN

WHERE

GROUP BY

WITH CUBE或WITH ROLLUP

HAVING

SELECT

DISTINCT

ORDER BY

TOP

请注意,这仅是一种常用执行顺序。SQL Server将根据查询的特定要求动态调整执行顺序。让我们更深入地了解MSSQL查询执行顺序。

FROM执行顺序

SELECT FirstName, LastName

FROM Person.Person

WHERE LastName LIKE 'A%'

ORDER BY LastName;

在此示例中,我们从Person.Person表中的FirstName和LastName列中选择,并按LastName列对其进行排序,只显示以字母 A 开头的 LastName。我们将从了解查询开始。

首先,SQL Server查找要查询的数据。查询中指定的表是Person.Person。在查询执行过程中,MSSQL首先选择表中的数据。然后,MSSQL根据WHERE子句中指定的条件来限制结果集。

表连接的FROM执行顺序

SELECT ProductID, Name, OrderQty

FROM Sales.SalesOrderDetail sod

JOIN Production.Product p ON sod.ProductID = p.ProductID

WHERE OrderQty > 100

ORDER BY Name ASC;

该查询假定Sales.SalesOrderDetail和Production.Product表中都有ProductId列来连接两个表。MSSQL实现的方式是,首先选择Sales.SalesOrderDetail表中的所有数据,然后使用ProductId列在Production.Product表中查找匹配的记录。

ON执行顺序

SELECT p.Name, sod.OrderQty, sod.LineTotal

FROM Sales.SalesOrderDetail sod

JOIN Production.Product p

ON sod.ProductID = p.ProductID

WHERE OrderQty > 100

ORDER BY Name ASC;

再看一下上面的查询,我们在Product表和SalesOrderDetail表之间使用JOIN来连接ProductId。在使用JOIN时,我们需要指定一个ON子句来指定两个表之间的匹配条件。

在查询中执行ON子句时,MSSQL仅考虑来自FROM子句指定的表和JOIN子句指定的表。因此,不要使用WHERE子句中的表别名在ON子句中引用列名。

JOIN执行顺序

SELECT Cust.CustomerID, Sales.SalesPersonID, Sales.SalesOrderId

FROM Sales.Customer Cust

LEFT JOIN Sales.SalesOrderHeader Sales

ON Cust.CustomerID = Sales.CustomerID

LEFT JOIN Sales.SalesPerson SalesPerson

ON Sales.SalesPersonID = SalesPerson.SalesPersonID

WHERE Cust.CustomerID < 10;

在此示例中,我们从Sales.Customer表中检索所有客户,以及对于每个客户的所有销售订单和销售人员。在这个例子中,我们使用了两个左连接,因为我们希望列出Sales.SalesOrderHeader和Sales.Person表中没有相关记录的客户。

在执行此查询时,首先对Sales.Customer执行查询,然后使用LEFT JOIN将Sales.SalesOrderHeader和Sales.SalesPerson表连接到Sales.Customer中以获取SalesOrderId和SalesPersonId。对于Sales.SalesOrderHeader和Sales.SalesPerson表,左连接将返回所有不匹配记录的空值。

WHERE执行顺序

SELECT FirstName, LastName

FROM Person.Person

WHERE LastName LIKE 'A%'

ORDER BY LastName;

MSSQL按以下顺序执行WHERE子句:

检查ON子句的逻辑是否正确。

根据WHERE子句中指定的条件筛选来自FROM子句的结果集。

如果HAVING子句出现在查询中,则根据HAVING子句中指定的条件筛选结果集。

在上面的示例中,MSSQL将从Person.Person表中选择所有FirstName和LastName数据。然后,MSSQL再次筛选这个结果集,只返回LastName以A开头的记录。

GROUP BY执行顺序

SELECT Series.SeriesCode, COUNT(*) AS ProductCount

FROM Production.Product

JOIN Production.ProductSeries AS Series ON Product.ProductSeries = Series.SeriesID

GROUP BY Series.SeriesCode

ORDER BY ProductCount DESC;

在此示例中,我们统计每个产品系列中产品的数量,并按ProductCount列对结果集进行降序排序。MSSQL按以下顺序执行GROUP BY子句:

根据SELECT子句中指定的列对结果集进行分组。

使用GROUP BY子句中指定的条件对分组进行筛选。

筛选结果集以返回汇总数据。

如果存在ORDER BY子句,则对汇总结果进行排序。

在上面的示例中,我们按SeriesCode分组,并计算产品的数量。MSSQL使用GROUP BY子句将结果集分组,并使用Series.SeriesCode列定义分组条件。之后,使用COUNT(*)函数计算每个组的产品数。

HAVING执行顺序

SELECT MONTH(OrderDate) AS OrderMonth, SUM(TotalDue) AS TotalDue

FROM Sales.SalesOrderHeader

GROUP BY MONTH(OrderDate)

HAVING SUM(TotalDue) > 100000

ORDER BY OrderMonth ASC;

在上面的示例中,我们将订单按OrderDate月份汇总,并使用HAVING子句筛选所有TotalDue的总和大于100,000美元的订单。MSSQL按照以下顺序执行HAVING:

使用GROUP BY子句中指定的列对结果集进行分组。

使用SUM()函数对分组结果进行求和。

使用HAVING子句中指定的条件对求和结果进行筛选。

如果存在ORDER BY子句,则对汇总结果进行排序。

SELECT执行顺序

SELECT FirstName, LastName

FROM Person.Person

WHERE LastName LIKE 'A%'

ORDER BY LastName;

MSSQL按以下顺序执行SELECT子句:

选定要返回哪些列。

根据列中指定的措辞和算术计算生成列的值。

在上面的示例中,MSSQL选择Person表中的FirstName和LastName列,并计算这些列中的每个值。然后,MSSQL按照LastName的字母顺序对结果集进行排序。

DISTINCT执行顺序

在SELECT子句中使用DISTINCT关键字可以返回唯一的记录。SELECT DISTINCT的执行顺序与标准SELECT的执行顺序相同。

ORDER BY执行顺序

SELECT FirstName, LastName

FROM Person.Person

WHERE LastName LIKE 'A%'

ORDER BY LastName;

在此示例中,我们从Person.Person表中选择FirstName和LastName列中的数据,并按LastName的字母顺序对其进行排序以返回结果集。ORDER BY子句是最后一步执行的。

在查询中使用ORDER BY时,请始终确保为ORDER BY子句中指定的所有列创建索引。这样做可以提高查询性能。

TOP执行顺序

SELECT TOP 10 * FROM Person.Person;

在此示例中,我们返回Person.Person表中的前10个记录。在使用TOP时,MSSQL按以下顺序执行:

根据FROM,JOIN,ON和WHERE子句筛选结果集。

对查询结果进行排序。

返回前N条记录。

结论

在编写MSSQL查询时,请了解查询执行顺序非常重要。通过了解查询操作的执行顺序,您可以更好地优化查询性能,并更好地了解查询的工作原理。这篇文章向您介绍了常用的MSSQL查询执行顺序。

免责声明:本文来自互联网,本站所有信息(包括但不限于文字、视频、音频、数据及图表),不保证该信息的准确性、真实性、完整性、有效性、及时性、原创性等,版权归属于原作者,如无意侵犯媒体或个人知识产权,请来电或致函告之,本站将在第一时间处理。猿码集站发布此文目的在于促进信息交流,此文观点与本站立场无关,不承担任何责任。

数据库标签