**SELECT**是SQL資料操縱語言（DML）中用於查詢表格内欄位資料的指令，可搭配條件限制的子句(如**where**)或排列順序的子句（如**order**）來获取查詢結果。

**SELECT**的基本語句格式。

> 
> ```
> SELECT [ALL | DISTINCT] 欄位名 [,欄位名...]
>  FROM 資料表名 [,資料表名...]
>  [WHERE 篩選條件式]
>  [GROUP BY 欄位名[,欄位名...]]
>  [ORDER BY 欄位名[,欄位名...]]
> 
> ```
>

简单範例
----

假設下方範例表格名稱為「T」；表格中有存有二列資料並以C1、C2 兩欄區分資料內容。

| C1 | C2 |
| --- | --- |
| wiki | 10 |
| wikipedia | 100 |

### 欄位查詢

以「\*」代表回傳全部的欄位內容 

| 查詢語句 | 回傳結果 |
| --- | --- |
| 
```
SELECT \* FROM T;

```
 | 

|  |  |
| --- | --- |
| wiki | 10 |
| wikipedia | 100 |

 |

或指定只查詢C1欄位資料

| 查詢語句 | 回傳結果 |
| --- | --- |
| 
```
SELECT C1 FROM T;

```
 | 

|  |
| --- |
| wiki |
| wikipedia |

 |

### 條件限制

以「where」來限制回傳C1欄位中完全符合條件的資料

| 查詢語句 | 回傳結果 |
| --- | --- |
| 
```
SELECT \* FROM T WHERE C1 = 'wiki';

```
 | 

|  |  |
| --- | --- |
| wiki | 10 |

 |

以「where」搭配「like」來回傳C1欄位中相似符合條件的資料

| 查詢語句 | 回傳結果 |
| --- | --- |
| 
```
SELECT \* FROM T WHERE C1 like 'wiki%';

```
 | 

|  |  |
| --- | --- |
| wiki | 10 |
| wikipedia | 100 |

 |

利用運算比較式來回傳C2欄位中符合數值大小的資料

| 查詢語句 | 回傳結果 |
| --- | --- |
| 
```
SELECT \* FROM T WHERE C2 > 50;

```
 | 

|  |  |
| --- | --- |
| wikipedia | 100 |

 |

语义
--

SELECT语句内部各组成部分的理论计算顺序，依次为：

1. FROM的表连接；
	1. 笛卡尔积
	2. ON连接条件筛选（完成了内部连接）
	3. 添加外部连接的行
2. WHERE子句篩選出满足條件的行集；
3. GROUP BY子句对行集中的行做分组合并，使得多个行对应于结果集中的一行；
4. 应用HAVING子句从中间结果筛选出满足条件的行的集合；
5. SELECT的结果列中的表达式，然后是DISTINCT关键字处理（如果有的话）。因此，在SELECT中给结果集中的列指定别名，是无法被WHERE子句或者GROUP BY子句或者HAVING可见并使用的。
6. 应用ORDER BY子句对结果集中的行排序。
7. 如果存在TOP或OFFSET/FETCH，对结果行的挑选。

如果使用了GROUP BY子句做分组合并，之后要引用的列必须是或者出现在GROUP BY子句中，或者被包含在聚合函数（如SUM、COUNT等）中。否则编译会报错。这是因为，上述两种情形的列对于每一个分组都有确定的单一值；而上述两种情形以外的列，对于每一个分组，有可能对应于原始行集的多个行从而具有多个不同的值，那么选择哪个值作为该分组的该列的值？无从选择。聚合函数计算时忽略掉列值为NULL的行。

HAVING子句是在分组后再做筛选，所以HAVING子句中可以包含聚合函数；而WHERE子句就不能包含聚合函数，因为WHERE子句是在分组之前计算的，那时根本无从计算聚合函数。例如，对销售表依据客户名称做分组合并，然后筛选出每个客户的订单合计金额大于100万元的情形，从而得到规模以上大客户的清单。

使用ORDER BY子句，可以按照单个列排序，也可以依次按照多个列排序，也可以按照结果集中列的别名排序，还可以使用结果集之外的列排序。但是，如果已经指定了SELECT DISTINCT或者该语句包含了GROUP BY子句，或是包含了UNION运算符，则排序列必须包含在结果集的列中。这是因为，在上述情形，原数据或者中间表的多个行对应于结果集中的一行；排序列如果不出现在结果集的列中，那么就可能使结果集中的一行对应于多行从而有了多个排序列的值，这行的排序情况就不唯一导致无从确定其排序后的顺位。可以使用ASC或者DESC关键字制定升序或降序，缺省为升序。

对于排序来说，更复杂的是不同字符编码所带来的比较规则的不同。例如，ASCII字符串的字典序比较与Unicode字符串的字典序比较，就完全不同。可以使用COLLATE子句指定显式排序规则。比较运算符以及MAX、MIN、BETWEEN、LIKE、IN等运算符都涉及到排序规则。

筛选条件表达式，可以使用=（相等）、>、<、>=、<=、<>等比较运算符，NOT逻辑非、AND、OR等逻辑运算符，BETWEEN或者NOT BETWEEN表示开区间或者其补集的所有值，IN关键字列出所有可行值（特别是在子查询中），LIKE关键字用于模式匹配查询。模式包括%代表任意字符串，\_代表单个任意字符，[]表示指定范围内的单个字符，[^]表示不在指定范围内的单个字符。可以用ESCAPE关键字定义转义字符，或者用[]包含按照字面使用的字符。

NULL值计算使用三值逻辑。谓词计算结果为TRUE、FALSE或者UNKNOWN。对于筛选条件表达式，SQL只接受TRUE。对于CHECK约束则是拒绝FALSE。两个NULL值是否相等，这取决于是否遵从ANSI标准。可以使用谓词IS NULL或者IS NOT NULL使得结果确定且唯一。 在GROUP BY或者ORDER BY子句，分组或排序时两个NULL视为相等。

对结果集中的列，可以使用关键字TOP选项，限制结果集中返回行数或者行数所占百分比。还可以紧随其后使用关键字WITH TIES，返回原结果集中最后一行的排序字段相等的所有行。例如，返回原始数据表中某列最大的那一行，如果使用关键字WITH TIES就会把并列最大的多行全部返回。

在SELECT之后紧随关键字DISTINCT，使得结果集中不含重复的行。关键字DISTINCT也可用于函数参数。

**子查询**是嵌套于SELECT、INSERT、UPDATE、DELETE等语句中的查询。按照子查询返回结果的数量，分为标量子查询和多值子查询；按照对外部查询的依赖性，分为独立子查询和相关子查询。子查询出现在SELECT语句的结果列表中，那么子查询应该是返回单一值；这种子查询往往可以用表的Join操作代替。子查询用在WHERE子句的表达式中，可以返回单一值用于比较运算符（>、<、>=等等）之后；也可以返回多值且有ANY、SOME、ALL等关键字前缀用于比较运算符之后；还可以返回多值与关键字IN、EXISTS、NOT IN、NOT EXISTS连用。子查询可以嵌套子查询。

資料參考
----

1. ↑  Itzik Ben-Gan:《Microsoft Sql Server 2012 high-performance T-sql using windows functions》

*. 歐萊禮 (O'REILLY). 2008. ISBN 978-986-6840-16-6.
*. 博碩文化. 2006. ISBN 957-527-908-5.

外部連結
----

* SELECT Syntax（Microsoft SQL Server） （页面存档备份，存于）
* SELECT Syntax（Firebird） （页面存档备份，存于）
* SELECT Syntax（MySql） （页面存档备份，存于）
* SELECT Syntax（PostgreSQL） （页面存档备份，存于）
* SELECT Syntax（SQLite） （页面存档备份，存于）


|  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
SQL |
| --- |
|  |
| 版本 | 
* SQL-86
* SQL-89
* SQL-92
* SQL:1999（英语：）
* SQL:2003（英语：）
* SQL:2006（英语：）
* SQL:2008（英语：）
* SQL:2011（英语：）
* SQL:2016（英语：）

 |
|  |
| 关键字 | 
* As（英语：）
* Case
* Create
* Delete
* From（英语：）
* Having（英语：）
* Insert
* Join
* Merge（英语：）
* Null
* Order by（英语：）
* Over
* Prepare（英语：）
* Select
* Truncate
* Union（英语：）
* Update
* Where（英语：）
* With（英语：）

 |
|  |
| 相关 | 
* 埃德加·科德
* 关系数据库

 |
|  |
| ISO/IEC SQL部分 | 
* Framework（英语：）
* Foundation（英语：）
* Call-Level Interface（英语：）
* Persistent Stored Modules（英语：）
* Management of External Data（英语：）
* Object Language Bindings（英语：）
* Information and Definition Schemas（英语：）
* SQL Routines and Types for the Java Programming Language（英语：）
* XML-Related Specifications（英语：）

 |

 |

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
数据库管理系统（DBMS） |
| --- |
|  |
| 概念 | 
* 数据库
	+ 理論
* 数据模型
* 数据库存储结构（英语：）
* 关系 (数据库)
* 关系模型
* 分布式数据库
* ACID
	+ 原子性（英语：）
	+ 一致性
	+ 隔離性
	+ 持久性
* Null值
* 数据库规范化
* 數據庫完整性
* 實體完整性
* 參照完整性
* 关系数据库管理系统
* 主键
* 外键
* 代理键
* 超键
* 候选键
* 事务处理
* 增刪查改

 |
|  |
| 数据库组件 | 
* 触发器
* 视图
* 数据库表
	+ 
	+
* 指标
* 事务日志（英语：）
* 数据库事务
* Savepoint
* 并发控制
* 乐观锁
* 悲观锁
* 数据库索引
* 存储程序
* 資料庫分割（英语：）

 |
|  |
| SQL | 

|  |  |
| --- | --- |
| 分类 | 
* 数据查询语言（DQL）
* 資料定義語言（DDL）
* 資料操縱語言（DML）
* 資料控制語言（DCL）

 |
|  |
| 指令 | 
* SELECT
* INSERT
* UPDATE
* MERGE
* DELETE
* JOIN
* UNION
* CREATE
* DROP
* Begin work
* COMMIT
* ROLLBACK
* TRUNCATE
* ALTER

 |
|  |
| 安全 | 
* 
* 參數化查詢

 |

 |
|  |
| 实现 | 

|  |  |
| --- | --- |
| 类型 | 
* 关系数据库
* 面向文檔的數據庫
* 平面文件数据库
* Deductive（英语：）
* 維度化資料庫
* 階層式
* 图数据库
* NoSQL
* NewSQL
* 对象数据库
* 物件關聯式資料庫（英语：）
* Temporal
* XML資料庫（英语：）

 |
|  |
| 数据库产品 | 
* 对象型
	+ 对比
* 关系型
	+ 对比

 |
|  |
| 数据库组件 | 
* 数据查询语言
* 查詢最佳化器（英语：）
* 查詢計畫（英语：）
* 嵌入式SQL
* ORM
* LINQ
* 数据访问层
* ODBC
* OLE DB
* ADO
* ADO.NET
* JDBC
* PDO

 |

 |

 |