正文共:5024 字 2 图 预计阅读时间:14 分钟
本文目录:
子查询是一个嵌套在 SELECT、INSERT、UPDATE 或 DELETE 语句或其他子查询中的查询。任何允许使用表达式的地方都可以使用子查询。
子查询也称为内部查询或内部选择,而包含子查询的语句也称为外部查询或外部选择。
有三种基本的子查询。它们是:
许多包含子查询的 Transact-SQL 语句都可以改用联接表示。其他问题只能通过子查询提出。
在 Transact-SQL 中,包含子查询的语句和语义上等效的不包含子查询的语句(即联接的方式)在性能上通常没有差别。但是,在一些必须检查存在性的情况中,使用联接会产生更好的性能。否则,为确保消除重复值,必须为外部查询的每个结果都处理嵌套查询。所以在这些情况下,联接方式会产生更好的效果。
子查询的 SELECT 查询总是使用圆括号括起来。它不能包含 COMPUTE 或 FOR BROWSE 子句,如果同时指定了 TOP 子句,则只能包含 ORDER BY 子句。
子查询受下列限制的制约:
子查询的例子可以参考笔试题中的例子,SQL笔试50题(上),SQL笔试50题(下)
通过联接,可以从两个或多个表中根据各个表之间的逻辑关系来检索数据。
联接条件可通过以下方式定义两个表在查询中的关联方式:
可以在 FROM 或 WHERE 子句中指定内部联接;而只能在 FROM 子句中指定外部联接。联接条件与 WHERE 和 HAVING 搜索条件相结合,用于控制从 FROM 子句所引用的基表中选定的行。
比如下列联接因为是内部联接,因此也可以改写为在WHERE条件中指定联接。
1-- FROM中指定联接(首选)
2SELECT pv.ProductID, v.BusinessEntityID, v.Name
3FROM Purchasing.ProductVendor AS pv
4JOIN Purchasing.Vendor AS v
5 ON (pv.BusinessEntityID = v.BusinessEntityID)
6WHERE StandardPrice > 10
7 AND Name LIKE N'F%';
8-- WHERE中指定联接
9SELECT pv.ProductID, v.BusinessEntityID, v.Name
10FROM Purchasing.ProductVendor AS pv, Purchasing.Vendor AS v
11WHERE pv.VendorID = v.VendorID
12 AND StandardPrice > 10
13 AND Name LIKE N'F%';
在 FROM 子句中指定联接条件有助于将这些联接条件与 WHERE 子句中可能指定的其他任何搜索条件分开,建议用这种方法来指定联接。简化的 ISO FROM 子句联接语法如下:
1FROM first_table
2join_type
3second_table
4[ON (join_condition)]
join_type 指定要执行的联接类型
join_condition 定义用于对每一对联接行进行求值的谓词(比较运算符或关系运算符)。
当 SQL Server 处理联接时,查询引擎会从多种可行的方法中选择最有效的方法来处理联接。由于各种联接的实际执行过程会采用多种不同的优化,因此无法可靠地预测。
联接的例子可以参考笔试题中的例子,SQL笔试50题(上),SQL笔试50题(下),在笔试题中有大量的内联接和左联接的例子。
UNION 运算符可以将两个或多个 SELECT 语句的结果组合成一个结果集。
UNION 的结果集列名与 UNION 运算符中第一个 SELECT 语句的结果集中的列名相同。另一个 SELECT 语句的结果集列名将被忽略。
默认情况下,UNION 运算符将从结果集中删除重复的行。如果使用 ALL (即UNION ALL)关键字,那么结果中将包含所有行而不删除重复的行。
使用 UNION 运算符时需遵循下列准则:
SELECT city AS Cities FROM stores_west
UNION
SELECT city FROM stores_east
ORDER
BY city
使用 EXCEPT 和 INTERSECT 运算符可以比较两个或更多 SELECT 语句的结果并返回非重复值。
使用 EXCEPT 或 INTERSECT 比较的结果集必须具有相同的结构。它们的列数必须相同,并且相应的结果集列的数据类型必须兼容。
INTERSECT 运算符优先于 EXCEPT。
公用表表达式 (CTE) 可以认为是在单个 SELECT、INSERT、UPDATE、DELETE 或 CREATE VIEW 语句的执行范围内定义的临时结果集。CTE 与派生表类似,具体表现在不存储为对象,并且只在查询期间有效。与派生表的不同之处在于,CTE 可自引用,还可在同一查询中引用多次。
CTE 可用于:
使用 CTE 可以获得提高可读性和轻松维护复杂查询的优点。查询可以分为单独块、简单块、逻辑生成块。之后,这些简单块可用于生成更复杂的临时 CTE,直到生成最终结果集。
可以在用户定义的例程(如函数、存储过程、触发器或视图)中定义 CTE。
CTE 由表示 CTE 的表达式名称、可选列列表和定义 CTE 的查询组成。定义 CTE 后,可以在 SELECT、INSERT、UPDATE 或 DELETE 语句中对其进行引用,就像引用表或视图一样。CTE 也可用于 CREATE VIEW 语句,作为定义 SELECT 语句的一部分。
CTE 的基本语法结构如下:
1WITH expression_name [ ( column_name [,...n] ) ]
2AS
3( CTE_query_definition )
4-- 运行 CTE 的语句
5SELECT <column_list>
6FROM expression_name;
1-- 定义 CTE 查询别名和列名称
2WITH Sales_CTE (SalesPersonID, SalesOrderID, SalesYear)
3AS
4-- 定义CTE查询的结果集
5(
6 SELECT SalesPersonID, SalesOrderID, YEAR(OrderDate) AS SalesYear
7 FROM Sales.SalesOrderHeader
8 WHERE SalesPersonID IS NOT NULL
9)
10-- 使用CTE查询的结果进行进一步的查询
11SELECT SalesPersonID, COUNT(SalesOrderID) AS TotalSales, SalesYear
12FROM Sales_CTE
13GROUP BY SalesYear, SalesPersonID
14ORDER BY SalesPersonID, SalesYear;
本文项目地址:
https://github.com/firewang/sql50
(喜欢的话,Star一下)
阅读原文,或者访问该链接可以在线观看(该系列将更新至GitHub,并且托管到read the docs)
https://sql50.readthedocs.io/zh_CN/latest/
参考网址:https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2008-r2/ms175995(v=sql.105)