介绍
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查询执行顺序。