翻译 Stairway to T-SQL DML Level 1: The Basic SELECT Statement
通往T-SQL DML Level 1的阶梯:基本的SELECT语句
来自 Gregory Larsen, 2011/10/07
系列
这篇文章是阶梯系列的一部分:通往T-SQL DML的阶梯。
通过使用SQL Server的Transact-SQL (T-SQL)语言,这个阶梯将为您提供如何使用SQL Server表的数据的基本理解。DML是数据操纵语言,是处理数据的语言的一方面。它包括语句的选择、插入、更新和删除。这个阶梯将提供一些SQL语言的历史和一些关于集合论的一般概念。每个级别都将建立在之前的级别之上,所以当你完成时,你将对如何从SQL Server中选择和修改数据有一个很好的理解。
下面是这个阶梯系列将会涵盖的不同的级别:
•第一级:基本的SELECT语句
•第二级:结构化查询语言(SQL)的历史
•第三级:关系数据库设计
•第四级:SQL的数学:第一部分
•第五级:SQL的数学:第二部分
•第六级:使用ORDER BY子句排序数据的基础
•第七级:使用简单的GROUP BY子句汇总数据
•第八级:修改数据:UPDATE
•第九级:修改数据:DELECT
第一级:基本的SELECT语句
在SQL Server数据库中管理数据有许多不同的方面,在处理与管理应用程序数据相关的复杂的管理问题之前,首先你需要从表中检索数据。要从SQL Server表中返回数据,你需要使用SELECT语句。在这个级别中,我将介绍基本SELECT语句的组件,以及如何使用它从单个的SQL Server表中检索数据。
SELECT语句的三个部分
从单个表中返回数据的基本SELECT语句包括三个不同的部分:Column list、FROM子句和WHERE子句。使用这些不同组件构造基本选择语句的语法如下所示:
“<Column List> ”将包含你想要返回的查询中的一个列的清单,“<table_name>”将包含被选中数据的表,以及“<where criteria>”能很好地确定将用于约束从SELECT语句返回的行的搜索条件。注意WHERE子句是可选的。
请注意,我在这个阶梯上的所有示例将使用AdventureWorks SQL Server 2005数据库,该数据库可以在此网址的Codeplex中获得:http://sqlserversamples.codeplex.com/。
让我们看看下面的非常简单的SELECT语句,这是从AdventureWorks数据库中的表中选择的一些数据。你可以使用SQL Server Management Studio中的查询窗口来运行本文中描述的每个查询语句,同时将数据库设置为AdventureWorks。
在这里,我从表Production.ProductCategory中选择了两个不同的列,ProductCategoryID和Name。由于这个SELECT语句有一个WHERE子句,所以它将限制只有ProductCategoryID的值小于2的行才能从表中返回。
现在你已经了解了SELECT语句的基本思想,让我更详细地向你介绍SELECT语句的每个组件。
Column List
Column list遵循SELECT关键字,并且是指定你想要从表中返回的列的位置。列通过指定列名来标识。如果多个列被列出,则用逗号分隔开来。在以后的级别中,我们将研究从指定表中除了列以外的返回值的可能性,在第一级中,我们将坚持学习基础知识。在上面的例子中,如果它只选择一个列,或者一个表的所有列,让我们来看看column list是什么样子的。
如果我只想返回Production的Name列。在表ProductCategory中我的查询是这样的:
在这里,你可以看到,我只在上述查询中的SELECT和FROM关键字之间指定了Name列。但是如果我想要指定Production中的所有列,在表ProductCategory中我将运行以下查询:
在这个SELECT语句中,你可以看到,我已经识别出了4个不同的列,每个列由一个逗号分隔开。这些列可以在单行上一起列出,也可以在不同的行上以不同的方式进行分类,就像我所做的那样。还有一种方法可以从表中选择所有列,就是通过指定星号而不是指定单个列名,下面是使用星号说明的SELECT语句:
在应用程序中使用星号(通常称为“星号”)时需要注意,由于星号将返回表中的所有列,如果您更改了表来包含一个额外的列,那么将在不修改实际SELECT语句的情况下返回额外的列。然而,如果你已经指定了所有列的名称,那么当添加一个新列时,它将不会返回,除非你将它添加到Column list中。使用星号可以接受测试,但是如果你想遵循最佳实践,请不要在应用程序代码中使用它。这是最佳实践的原因是大多数应用程序期望能从给定的SELECT语句中返回固定数量的列。当将列添加到表中,并且使用星号方法来识别表列时,返回的附加列可以破坏未被编码处理的这些额外数据的应用程序。
FROM子句
在FROM子句中,你确定想要从中选择数据的表。在这个级别,我们只讨论从FROM子句中的单个表中选择数据。注意,当你在SQL知识中取得进展时,FROM子句可以识别从中选择数据的多个表。
有许多不同的方法来确定要选择数据的表。事实上有四种不同的方式,其中三种我会在这篇文章中写明,第四种我只会提及一下。
第一种方法是通过标识表名和它所属的模式来指定一个表。这是迄今为止我在所有示例中识别所有表名的方法。在我的每一个例子中,我所说的表名都是Production.ProductCategory。实际的表名只是ProductCategory,它包含在Production模式中。
在FROM子句中确定表的第二种方法是只声明表名。当FROM子句只包含表名时,SQL Server将假定表包含在数据库用户的默认模式下,或在dbo模式下。让我再详细解释一下这个概念。
当您向仅标识表名的SQL Server提交查询时,SQL Server将需要解析该表所处的架构。这是因为在给定的数据库中可以有多个同名的表,只要它们在不同的模式中。要确定一个表驻留在SQL Server中的架构,需要经过两个步骤。第一步是对提交查询的数据库用户使用默认架构,并附加他们的默认架构表名,然后查找该表。如果SQL Server使用用户默认架构找到表,则不执行步骤二。如果SQL Server没有使用用户默认架构找到表,则SQL Server将检查dbo架构以查找表。无论您的数据库是否包含单个模式,最好的做法是习惯于使用模式名称后面的表名来标识FROM子句中的表。通过这样做,您可以减少SQL Server解析表名和促进计划缓存重新使用所需的工作量。
识别表的第三种方法是使用三个部分名,其中最后两个部分是模式和表名,第一部分是数据库名。这里有一个SELECT语句,类似于我以前的SELECT语句,它使用了三个部分的名称:
在这里,您可以看到,我将数据库名AdventureWorks附加到在FROM子句中标识的Production.ProductClass表中。
通过使用FROM子句中表的三部分命名约定,可以将SQL Server Management Studio中查询窗口的数据库上下文设置为任何数据库,而且数据库引擎仍将知道用于查询的数据库、架构和表。当构建需要从实例中的多个数据库检索数据的应用程序时,使用三个部分名称有助于从单个应用程序中的多个数据库检索数据。
最后一种方法是使用四部分的名称,第四部分(在数据库名称之前)标识链接服务器的名称。由于链接服务器超出了本阶梯的范围,我将不再进一步讨论这个主题。如果您应该跨包含4个部分的表名运行,您将知道该表与链接服务器相关联。
WHERE 子句
SELECT语句的WHERE子句是可选的。WHERE子句用于约束SELECT语句返回的行。数据库引擎根据WHERE子句计算每一行,然后只返回符合WHERE子句中标识的搜索条件的行。当您编写更多SELECT语句时,您会发现大多数SELECT语句可能包含WHERE子句。
简单WHERE子句将包含单个搜索条件,而更复杂的WHERE子句可能包含许多条件。当在WHERE子句中使用多个条件时,它们将通过使用AND和OR逻辑运算符逻辑地组合在一起。SELECT语句中可能包含的不同条件的数量没有限制。在我的例子中,到目前为止,我只使用了一个条件。让我们回顾几个有更复杂的WHERE子句的例子。
下面是一个SELECT语句,它有两个不同的搜索条件:
在这个语句中,第一个条件检查行是否在Color列中有值Blue。第二个条件检查Productld列中的值是否大于900。由于使用了AND操作符,为了从此查询返回一行,这两个条件都必须为true。
让我们看一个WHERE子句,它变得更加复杂了:
此示例返回Production.Product行,其中ProductLD值大于900,Color列中的值为Blue或Green。通过查看这个查询,您可以看到我在两个不同的Color列条件周围放置了括号。这设置了条件之间相互评估的顺序,就像在数学表达式中所做的那样。通过使用括号,在计算AND运算符之前,将计算两种颜色条件之间的OR操作。在不带括号的情况下使用AND和OR时,这些逻辑运算符是进程的顺序是基于逻辑运算符优先的规则。优先级规则规定,如果不包含括号,则在OR操作之前执行AND操作。
让我在前面的WHERE子句的基础上添加一个NOT操作符:
我在AND操作之后添加了NOT运算符,以表明我想要的产品不是蓝色或绿色。当我对AdventureWorks数据库运行这个查询时,我得到的产品是银色、黄色和黑色。
有关搜索条件的所有不同可能性的完整列表,请参阅联机丛书: http://msdn.microsoft.com/en-us/library/ms173545.aspx, 有关逻辑运算符优先级的更多信息,请阅读以下主题:http://msdn.microsoft.com/en-us/library/ms190276.aspx.
把所有的东西放在一起:商业案例
现在轮到您使用我共享的信息来构建您自己的基本SELECT语句了。在本节中,我将为您提供几个练习,您可以练习编写一个SELECT语句来满足所描述的业务案例。
练习 #1:
假设人力资源部门负责人要求您为有大量病假和休假时间的员工提供所有EmployeeID值的列表。就这份清单而言,人力资源部主管告诉你“大量休假”的定义如下:员工的SickLeaveHours值必须大于68,VacationHours值必须大于98。您可以在Human.Resources.Employee表中找到这些列和EmployeeID列。根据AdventureWorks数据库编写和测试代码。完成后,根据下面一节中的答案检查代码。
练习 #2:
有一些问题,你的经理有几个具体的订单号码。您的经理希望您生成与几个特定订单相关联的所有列的列表,以便她可以查看与每个订单关联的哪个销售人员。您的经理指定,她只对包含SalesOrderHeader行的报表感兴趣,该报表的订单的SalesOrderId介于43702和43712之间。写完这个SELECT语句后,请检查下面的答案。
练习#1的答案:
您的查询应该如下所示:
查询的结果应该返回以下三行:
练习#2的答案:
如果您阅读上面引用的文档来了解更多关于搜索条件和中间操作符的信息,那么查询应该是这样的:
或者您可能编写了类似于以下代码的代码:
您的查询应该返回11行。5行的OrderDate Vale为2001-07-02,5行的OrderDate Vale为2001-07-03,2行的OrderDate值为2001-07-04。
与以前的解决方案相比,要注意的一点是,所有的列名都是标识出来的,而前一个解决方案使用星号来指定所有列。按名称标识所有列是一种更好的编码做法,因为SELECT语句将始终返回相同数量的列,即使向表中添加了其他列。当应用程序期望从SELECT语句返回特定数量的列时,这一点非常重要。
理解基本SELECT语句
要成为SQL Server应用程序程序员,首先需要了解基本的SELECT语句。了解如何检索表中的所有数据和约束返回的内容是开发应用程序的基础。本文和练习为您提供了SELECT语句基础,这是本系列的第一个构建块。
本文是T-SQL DML楼梯的一部分。