SELECT
本主题适用于: SQL Server (starting with 2008) Azure SQL Database Azure SQL Data Warehouse Parallel Data Warehouse
在SQL Server中,从数据库中检索行,并启用一个或多个行的选区,或者检索来自一个或多个表的列。SELECT语句的完整句法很复杂,但是主要的子句可以总结如下:
[ WITH { [ XMLNAMESPACES ,] [ <common_table_expression>] } ]
SELECT select_list [ INTO new_table ]
[ FROM table_source ] [ WHERE search_condition ]
[ GROUP BY group_by_expression ]
[ HAVING search_condition ]
[ ORDER BY order_expression [ ASC | DESC ] ]
UNION、EXCEPT和INTERSECT运算符可以用在查询之间,以组合结果、或者比较结果到一个结果集合中。
句法
-- Syntax for SQL Server and Azure SQL Database <SELECT statement> ::= [ WITH { [ XMLNAMESPACES ,] [ <common_table_expression> [,...n] ] } ] <query_expression> [ ORDER BY { order_by_expression | column_position [ ASC | DESC ] } [ ,...n ] ] [ <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 > ]
-- Syntax for Azure SQL Data Warehouse and Parallel Data Warehouse [ 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> ] [ ORDER BY <order_by_expression> ] [ OPTION ( <query_option> [ ,...n ] ) ]
备注
因为SELECT语句的复杂性,详细句法元素以及参数按子句显示:
WITH XMLNAMESPACES WITH common_table_expression | HAVING |
SELECT Clause | UNION |
INTO Clause | EXCEPT and INTERSECT |
FROM | ORDER BY |
WHERE | FOR Clause |
GROUP BY | OPTION Clause |
在SELECT语句中,子句的顺序是很重要的。任何可选的子句都可以省略掉,但是如果用到了可选的子句,它们就一定得以适当的顺序出现。
在用户定义函数中允许出现一些SELECT语句,这些语句的选择列表可以包含一些表达式,这些表达式把值赋给函数的本地变量。
一个四部分名结构与OPENDATASOURCE函数配合使用,作为服务器名部分,可以用作表源,无论这个表名是否出现在一个SELECT语句中。不能针对Azure SQL数据库指定四部分名。
一些应用到SELECT语句的句法约束涉及到远程表。
SELECT语句的逻辑处理顺序
下面的步骤显示了针对SELECT语句的逻辑处理顺序,或者绑定顺序。这个顺序确定了一个步骤中定义的对象什么时候对后续步骤中的子句可用。举个例子,如果查询处理可以绑定到(访问)定义在FROM子句中的表或视图,这些对象和它们的列对所有后面的步骤可用。相较之下,因为SELECT子句在第8步,所以定义在该子句中的所有的列别名或派生列,不能被前面的子句引用。然而,它们可以被后面的子句,比如说ORDER BY子句引用。注意语句的实际物理执行由查询处理决定,这顺序可能与本列表有很大的不同。
- FROM
- ON
- JOIN
- WHERE
- GROUP BY
- WITH CUBE or WITH ROLLUP
- HAVING
- SELECT
- DISTINCT
- ORDER BY
- TOP
授权
选择数据需要表或视图上的SELECT授权,它可以继承自更高的使用范围,比如说说架构上的SELECT授权,或者表上的CONTROL授权。或者要求加入db_datareader或db_owner固定数据库角色,或者sysadmin固定数据库角色。使用SELECT INTO创建一个新表,也要求有CREATETABLE授权,以及拥有这个新表的架构上的ALTERSCHEMA授权。
Examples: Azure SQL Data Warehouse and Parallel Data Warehouse
A. 使用SELECT语句来检索行和列
本部分显示了三个代码示例。第一段代码示例从AdventureWorksPDW2012数据库的DimEmployee
表中返回所有行(指定WHERE子句)以及所有列(使用*
)。
-- Uses AdventureWorks SELECT * FROM DimEmployee ORDER BY LastName;
下面的示例使用表别名来取得同样的结果。
-- Uses AdventureWorks SELECT e.* FROM DimEmployee AS e ORDER BY LastName;
这个示例从AdventureWorksPDW2012数据库的DimEmployee
表中返回所有行(没有指定WHERE子句)以及列的一个子集(FirstName
、LastName
、StartDate
)第三列的标题被重命名为FirstDay
。
-- Uses AdventureWorks SELECT FirstName, LastName, StartDate AS FirstDay FROM DimEmployee ORDER BY LastName;
该示例只返回DimEmployee
中EndDate
不是NULL,而且MaritalStatus
是“M”(已婚)的行。
-- Uses AdventureWorks SELECT FirstName, LastName, StartDate AS FirstDay FROM DimEmployee WHERE EndDate IS NOT NULL AND MaritalStatus = 'M' ORDER BY LastName;
B. 使用SELECT配合列标题以及计算
下面的示例从DimEmployee
表中返回所有的行,并为每个雇员根据他们的BaseRate
和每周40小时工作,计算工资总额。
-- Uses AdventureWorks SELECT FirstName, LastName, BaseRate, BaseRate * 40 AS GrossPay FROM DimEmployee ORDER BY LastName;
C. 使用DISTINCT配合SELECT
下面的示例使用DISTINCT
来生成一个列表,是DimEmployee
表中所有独一无二的Title。
-- Uses AdventureWorks SELECT DISTINCT Title FROM DimEmployee ORDER BY Title;
D. 使用GROUP BY
下面的示例针对每天的所有销售,找出总额。
-- Uses AdventureWorks SELECT OrderDateKey, SUM(SalesAmount) AS TotalSales FROM FactInternetSales GROUP BY OrderDateKey ORDER BY OrderDateKey;
因为GROUP BY
子句,每天只返回一行,包含了当天所有的销售的总额。
E. 使用GROUP BY配合多组
下面的示例为每天查找互联网销售的平均价格和总额,按下单的日期以及促销键分组。
-- Uses AdventureWorks 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日的行之后,把结果放到组中。
-- Uses AdventureWorks SELECT OrderDateKey, SUM(SalesAmount) AS TotalSales FROM FactInternetSales WHERE OrderDateKey > '20020801' GROUP BY OrderDateKey ORDER BY OrderDateKey;
G. 使用GROUP BY配合一个表达式
下面的示例按表达式分组。如果该表达式不包含合计函数,你就可以按这个表达式分组。
-- Uses AdventureWorks SELECT SUM(SalesAmount) AS TotalSales FROM FactInternetSales GROUP BY (OrderDateKey * 10);
H. 使用GROUP BY配合ORDER BY
下面的示例查找每天的销售总额,按日期排序。
-- Uses AdventureWorks SELECT OrderDateKey, SUM(SalesAmount) AS TotalSales FROM FactInternetSales GROUP BY OrderDateKey ORDER BY OrderDateKey;
I. 使用HAVING子句
下面的查询使用HAVING
子句以约束结果。
-- Uses AdventureWorks SELECT OrderDateKey, SUM(SalesAmount) AS TotalSales FROM FactInternetSales GROUP BY OrderDateKey HAVING OrderDateKey > 20010000 ORDER BY OrderDateKey;