适用于:SQL Server
Azure SQL 数据库
Azure SQL 托管实例
Azure Synapse Analytics
Microsoft Fabric中的SQL分析端点
Microsoft Fabric中的仓库
Microsoft Fabric中的SQL数据库
SELECT使用语句从数据库检索行。
SELECT 允许从 SQL Server 数据库引擎中的一个或多个表中选择一个或多个行或列。
由于完整的语法 SELECT 语句很复杂,因此每个子句都显示详细的语法元素和参数。 请参阅 “语法 ”部分,了解这些子句如何协同工作。
- 使用 XML命名空间
- 与common_table_expression
- SELECT 条款
- INTO条款
- FROM 子句(包括 JOIN、APPLY 和 PIVOT)
- WHERE 子句
- GROUP BY 子句
- HAVING 子句
- 限定条款(仅限Fabric Data Warehouse)
- WINDOW 子句
- ORDER BY 子句
可以在查询之间使用 UNION、EXCEPT 和 INTERSECT 运算符将其结果合并或比较为一个结果集。
Syntax
SQL Server 和 Azure SQL 数据库的语法:
<SELECT statement> ::=
[ WITH { [ XMLNAMESPACES , ] [ <common_table_expression> [ , ...n ] ] } ]
<query_expression>
[ ORDER BY <order_by_expression> ]
[ <FOR Clause> ]
[ OPTION ( <query_hint> [ , ...n ] ) ]
<query_expression> ::=
{ <query_specification> | ( <query_expression> ) }
[ { UNION [ ALL ] | EXCEPT | INTERSECT }
<query_specification> | ( <query_expression> ) [ ...n ] ]
<query_specification> ::=
SELECT [ ALL | DISTINCT ]
[ TOP ( expression ) [ PERCENT ] [ WITH TIES ] ]
<select_list>
[ INTO new_table ]
[ FROM { <table_source> } [ , ...n ] ]
[ WHERE <search_condition> ]
[ <GROUP BY> ]
[ HAVING <search_condition> ]
[ ; ]
Azure Synapse Analytics 和 Microsoft Fabric 的语法:
[ WITH <common_table_expression> [ , ...n ] ]
SELECT <select_criteria>
[ ; ]
<select_criteria> ::=
[ TOP ( top_expression ) ]
[ ALL | DISTINCT ]
{ * | column_name | expression } [ , ...n ]
[ FROM { table_source } [ , ...n ] ]
[ WHERE <search_condition> ]
[ GROUP BY <group_by_clause> ]
[ HAVING <search_condition> ]
[ QUALIFY <filter_condition> ]
[ ORDER BY <order_by_expression> ]
[ OPTION ( <query_option> [ , ...n ] ) ]
Remarks
语句中 SELECT 子句的顺序非常重要。 可以省略可选子句,但这些子句在使用时必须按适当的顺序出现。
SELECT 仅当这些语句的选择列表包含为函数局部变量赋值的表达式时,才允许在用户定义的函数中使用语句。
使用函数作为服务器名称部件构造 OPENDATASOURCE 的四部分名称可用作表源,无论表名出现在语句中 SELECT 的位置。 无法为Azure SQL 数据库指定四部分名称。
某些语法限制适用于 SELECT 涉及远程表的语句。
SELECT 语句的逻辑处理顺序
以下步骤显示了语句的逻辑处理顺序或绑定顺序 SELECT 。 此顺序确定在一个步骤中定义的对象何时可用于后续步骤中的子句。 例如,如果查询处理器可以绑定到子句中 FROM 定义的表或视图(access),则这些对象及其列可用于所有后续步骤。 相反,由于子 SELECT 句是步骤 8,因此该子句中定义的任何列别名或派生列都不能由前面的子句引用。 但是,后续子句(如 ORDER BY 子句)可以引用它们。 查询处理器确定语句的实际物理执行,顺序可能与此列表不同。
FROMONJOINWHEREGROUP BY-
WITH CUBE或WITH ROLLUP HAVING-
QUALIFY(仅限Fabric Data Warehouse) SELECTDISTINCTORDER BYTOP
Warning
在某些情况下,以前的序列可能有所不同。 假设视图上有聚集索引,视图排除一些表行,视图的 SELECT 列列表使用将 CONVERT 数据类型从 varchar 更改为 int。在这种情况下, CONVERT 可以在子句执行之前 WHERE 执行。 通常,如果视图很重要,可以修改视图以避免不同的序列。
Permissions
选择数据需要 SELECT 对表或视图具有权限,该权限可以继承自更高的范围,例如 SELECT 对架构的权限或 CONTROL 表的权限。 或者要求具有 db_datareader 或 db_owner 固定数据库角色或 sysadmin 固定服务器角色的成员身份 。 使用 SELECT INTO 创建新表还需要 CREATE TABLE 权限以及 ALTER SCHEMA 拥有新表的架构的权限。
Examples
以下示例使用 AdventureWorksPDW2022 数据库。
A. 使用 SELECT 检索行和列
本部分演示三个代码示例。 第一个代码示例返回表中的所有行(未WHERE指定子句)和所有列(使用*)。DimEmployee
SELECT *
FROM DimEmployee
ORDER BY LastName;
此第二个示例使用表别名实现相同结果。
SELECT e.*
FROM DimEmployee AS e
ORDER BY LastName;
本示例从 AdventureWorksPDW2022WHERE返回所有行(未FirstName指定子句)和列(LastName、StartDate)DimEmployee子集。 第三个列标题重命名为 FirstDay。
SELECT FirstName,
LastName,
StartDate AS FirstDay
FROM DimEmployee
ORDER BY LastName;
本示例仅返回该行的DimEmployee行,该行EndDate不具有该行和一个NULLMaritalStatus(已M婚)。
SELECT FirstName,
LastName,
StartDate AS FirstDay
FROM DimEmployee
WHERE EndDate IS NOT NULL
AND MaritalStatus = 'M'
ORDER BY LastName;
B. 将 SELECT 与列标题和列计算一起使用
下面的示例返回 DimEmployee 表中的所有行,并基于每位员工的 BaseRate 和 40 小时工作周计算他们的总工资。
SELECT FirstName,
LastName,
BaseRate,
BaseRate * 40 AS GrossPay
FROM DimEmployee
ORDER BY LastName;
C. 将 DISTINCT 与 SELECT 一起使用
下面的示例使用 DISTINCT 为 DimEmployee 表中的所有唯一标题生成列表。
SELECT DISTINCT Title
FROM DimEmployee
ORDER BY Title;
D. 使用 Group By
下面的示例查找每天所有销售的总金额。
SELECT OrderDateKey,
SUM(SalesAmount) AS TotalSales
FROM FactInternetSales
GROUP BY OrderDateKey
ORDER BY OrderDateKey;
由于使用了 GROUP BY 子句,因此每天只返回一行销售总额。
E. 对多个组使用 GROUP BY
下面的示例查找平均价格和每天的互联网销售总额(按订单日期和促销关键字进行分组)。
SELECT OrderDateKey,
PromotionKey,
AVG(SalesAmount) AS AvgSales,
SUM(SalesAmount) AS TotalSales
FROM FactInternetSales
GROUP BY OrderDateKey, PromotionKey
ORDER BY OrderDateKey;
F. 使用 GROUP BY 和 WHERE
下面的示例在只检索订单日期晚于 2002 年 8 月 1 日的行后对结果进行分组。
SELECT OrderDateKey,
SUM(SalesAmount) AS TotalSales
FROM FactInternetSales
WHERE OrderDateKey > '20020801'
GROUP BY OrderDateKey
ORDER BY OrderDateKey;
G. 将 GROUP BY 与表达式一起使用
以下示例按表达式进行分组。 如果表达式不包含聚合函数,则可以按表达式进行分组。
SELECT SUM(SalesAmount) AS TotalSales
FROM FactInternetSales
GROUP BY (OrderDateKey * 10);
H. 将 GROUP BY 与 ORDER BY 一起使用
下面的示例查找每天的总销售额以及当天的订单。
SELECT OrderDateKey,
SUM(SalesAmount) AS TotalSales
FROM FactInternetSales
GROUP BY OrderDateKey
ORDER BY OrderDateKey;
I. 使用 HAVING 子句
此查询使用 HAVING 子句限制结果。
SELECT OrderDateKey,
SUM(SalesAmount) AS TotalSales
FROM FactInternetSales
GROUP BY OrderDateKey
HAVING OrderDateKey > 20010000
ORDER BY OrderDateKey;