T-SQL笔记1:SELECT及SELECT高级应用

本章摘要

1:安装AdventureWorks

2:基本运算符和表达式

3:between

4:like

5:escape

6:TOP

7:GROUP BY

7.1:GROUP BY ALL

7.2:HAVING

8:SELECT字句技术

8.1:使用DISTINCT消除重复值

8.2:返回拼接的结果

8.3使用INTO字句

9:子查询

9.1:子查询类型

9.2:代替表达式的查询

  9.3:多层嵌套

10:比较使用 EXISTS 和 IN 的查询

11:联接
  11.1:使用衍生表

11.2:UNION

12:TABLESAMPLE

13:公共表表达式common_table_expression

1:安装AdventureWorks

本系列笔记均基于AdventureWorks数据库,有关AdventureWorks的安装帮助如下:

在 Management Studio 工具栏上,单击“文件”,指向“打开”,然后单击“文件”

浏览到文件 instawdb.sql,并单击“打开”。该文件的默认位置为 C:\Program Files\Microsoft SQL Server\90\Tools\Samples\AdventureWorks OLTP。

运行脚本之前,在脚本中找到语句 SET @data_path = @sql_path + 'AWDB\';,并更改该语句使其指向 instawdb.sql 脚本的位置。例如,SET @data_path = 'C:\Program Files\Microsoft SQL Server\90\Tools\Samples\AdventureWorks OLTP\';

执行脚本。

2:基本运算符和表达式

运算符 描述
!=
!>
!<
<
<=
<>
=
>
>=
ALL 比较标量值和单列集中的值。
ANY 比较标量值和单列集中的值。SOME 和 ANY 是等效的
BETWEEN 自动根据SQL的型别进行取值
CONTAINS 为单词或短语执行模糊搜索
ESCAPE 指定要以字面值形式搜索,而不是被解释为通配符
EXISTS 指定一个子查询,测试行是否存在
FREETEXT 根据意思,而不是字面值来搜索数据中的单词
IN WHERE color in (‘red’,‘blue’)
IS NOT NULL
IS NULL 检测NULL值
LIKE 根据通配符进行模式匹配
NOT BETWEEN
NOT IN
NOT LIKE
SOME 比较标量值和单列集中的值。SOME 和 ANY 是等效的

3:between

使用:

select SalesOrderID, ShipDate from Sales.SalesOrderHeader
where ShipDate between '7/28/2002' and '7/29/2002'

结果:将会返回17条语句。

也许有人会用,使用:

where'7/28/2002' < ShipDate and ShipDate < '7/29/2002'

不行吗?答案是不行。结果会返回0。

4:like

存在如下通配符,

%:0~N个任意字符;

_:1个字符;

[]:指定范围或列表中的任何单个字符;

[^]:指定不再范围中的任何单个字符;

5:escape

where name like ‘b/B%’ escape ‘/’

解析:表示全部以‘b/B’开头的name,其中/不理解为通配符。

6:TOP

top允许根据定义的行的数量或者百分比查询出开始的N行。如:

select top 10 from …

或者:

declare @percentage float

set @percentage =1

select top (@percentage)  percent * from Sales.SalesOrderHeader

7:GROUP BY

指定用来放置输出行的组。如果 SELECT 子句 <select list> 中包含聚合函数,则 GROUP BY 将计算每组的汇总值。

上面这句话不太好理解,更好的理解应该解释为:

由于在SELECT字句中使用了聚合函数,未聚合的列必须出现在GROUP BY子句中。”

select OrderDate, sum(totalDue) TotalDueByOrderDate from Sales.SalesOrderHeader
where ShipDate between '7/28/2002' and '7/29/2002'
group by OrderDate

结果:

(2 行受影响)

7.1:GROUP BY ALL

在上面的代码中,加入ALL,即:

select OrderDate, sum(totalDue) TotalDueByOrderDate from Sales.SalesOrderHeader
where ShipDate between '7/28/2002' and '7/29/2002'
--group by OrderDate
group by all OrderDate

结果:

Warning: Null value is eliminated by an aggregate or other SET operation.

(1124 行受影响)

这说明:ALL包含所有组和结果集,甚至包含那些其中任何行都不满足 WHERE 子句指定的搜索条件的组和结果集。如果指定了 ALL,将对组中不满足搜索条件的汇总列返回空值。

7.2:HAVING

指定组或聚合的搜索条件。HAVING 只能与 SELECT 语句一起使用。HAVING 通常在 GROUP BY 子句中使用。如果不使用 GROUP BY 子句,则 HAVING 的行为与 WHERE 子句一样。

相当于对GROUP之前的查询内容进行再一次的条件检索。

以下示例使用简单 HAVING 子句从 SalesOrderDetail 表中检索超过 $100000.00 的每个 SalesOrderID 的总计。

SELECT SalesOrderID, SUM(LineTotal) AS SubTotal
FROM Sales.SalesOrderDetail
--where ModifiedDate between '7/28/2002' and '7/29/2002'
GROUP BY SalesOrderID
HAVING SUM(LineTotal) > 100000.00
--HAVING SalesOrderID = 43875
--HAVING ModifiedDate between '7/28/2002' and '7/29/2002' --error
ORDER BY SalesOrderID ;

8:SELECT字句技术

        SELECT字句技术有很多,除了最简单的拼接等,下面介绍个人认为最有用的。

8.1:使用DISTINCT消除重复值

select * FROM HumanResources.Employee

结果:(290 行受影响)
select DISTINCT HireDate FROM HumanResources.Employee

结果:(164 行受影响)

说明已经将重复的抵消了。

8.2:返回拼接的结果

DECLARE @Shifts varchar(20)
SET @Shifts = ''
SELECT @Shifts = @Shifts + s.Name + ',' FROM HumanResources.Shift s
SELECT @Shifts

返回的结果为:Day,Evening,Night,

这对于我们处理简单的查询并提高效率有很大的好处。

8.3使用INTO字句

INTO字句用来创建新表(对我来说便是备份数据)。

一种典型的用法是复制数据到新表(这个新表可以被创建为永久表、临时表或全局临时表),如下代码:

SELECT CustomerID, Name, SalesPersonID, Demographics
INTO  Store_Archive
FROM Sales.Store

结果:(701 行受影响)

说明,1:创建了新表Store_Archive,2:有701行数据被复制到了Store_Archive。

当然,如果你仅仅想创建新表,而不想复制任何数据,有一个简洁的方法是:

SELECT CustomerID, Name, SalesPersonID, Demographics
INTO  Store_Archive
FROM Sales.Store
WHERE 1=0

9:子查询

子查询是一个嵌套在 SELECT、INSERT、UPDATE 或 DELETE 语句或其他子查询中的查询。任何允许使用表达式的地方都可以使用子查询。

联接总是可以表示为子查询。子查询经常(但不总是)可以表示为联接。这是因为联接是对称的:无论以何种顺序联接表 A 和 B,都将得到相同的结果。而对子查询来说,情况则并非如此。

使用联接而不使用子查询处理该问题及类似问题的一个不同之处在于,联接使您可以在结果中显示多个表中的列。例如,如果要在结果中包括产品子类别的名称,则必须使用联接版本。

9.1:子查询类型

可以在许多位置指定子查询(必须全部掌握):

9.2:代替表达式的查询

必须着重说说代替表达式的子查询。在 Transact-SQL 中,除了在 ORDER BY 列表中以外,在 SELECT、UPDATE、INSERT 和 DELETE 语句中任何能够使用表达式的地方都可以用子查询替代。

以下示例说明如何使用此增强功能。此查询找出所有山地车产品的价格、平均价格以及两者之间的差价。

USE AdventureWorks;
GO
SELECT Name, ListPrice,
(SELECT AVG(ListPrice) FROM Production.Product) AS Average,
ListPrice - (SELECT AVG(ListPrice) FROM Production.Product)
AS Difference
FROM Production.Product
WHERE ProductSubcategoryID = 1
 
9.3:多层嵌套

子查询自身可以包括一个或多个子查询。一个语句中可以嵌套任意数量的子查询。

以下查询将查找作为销售人员的雇员的姓名。

Use AdventureWorks;
GO
SELECT LastName, FirstName
FROM Person.Contact
WHERE ContactID IN
(SELECT ContactID
FROM HumanResources.Employee
WHERE EmployeeID IN
(SELECT SalesPersonID
FROM Sales.SalesPerson)
 

10:比较使用 EXISTS 和 IN 的查询

以下示例比较了两个语义等同的查询。第一个查询使用 EXISTS,第二个查询使用 IN

USE AdventureWorks ;
GO
SELECT a.FirstName, a.LastName
FROM Person.Contact AS a
WHERE EXISTS
(SELECT *
FROM HumanResources.Employee AS b
WHERE a.ContactId = b.ContactID
AND a.LastName = 'Johnson');
GO

下面的查询使用 IN

USE AdventureWorks ;
GO
SELECT a.FirstName, a.LastName
FROM Person.Contact AS a
WHERE a.LastName IN
(SELECT a.LastName
FROM HumanResources.Employee AS b
WHERE a.ContactId = b.ContactID
AND a.LastName = 'Johnson');
GO

以下是其中任一查询的结果集。

FirstName                                          LastName
-------------------------------------------------- ----------
Barry Johnson
David Johnson
Willis Johnson
(3 row(s) affected)
 
11:联接
   通过联接,可以从两个或多个表中根据各个表之间的逻辑关系来检索数据。
   联接条件中用到的列不必具有相同的名称或相同的数据类型。但如果数据类型不相同,则必须兼容,或者是可由 SQL Server 进行隐式转换的类型。

联接可分为以下几类:

  • 内部联接(典型的联接运算,使用类似于 = 或 <> 的比较运算符)。内部联接包括同等联接和自然联接。
    内部联接使用比较运算符根据每个表的通用列中的值匹配两个表中的行。例如,检索 studentscourses 表中学生标识号相同的所有行。
  • 外部联接。外部联接可以是左向外部联接、右向外部联接或完整外部联接。
    在 FROM 子句中可以用下列某一组关键字来指定外部联接:
    • LEFT JOIN 或 LEFT OUTER JOIN。
      左向外部联接的结果集包括 LEFT OUTER 子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某一行在右表中没有匹配行,则在关联的结果集行中,来自右表的所有选择列表列均为空值。
    • RIGHT JOIN 或 RIGHT OUTER JOIN
      右向外部联接是左向外部联接的反向联接。将返回右表的所有行。如果右表的某一行在左表中没有匹配行,则将为左表返回空值。
    • FULL JOIN 或 FULL OUTER JOIN
      完整外部联接将返回左表和右表中的所有行。当某一行在另一个表中没有匹配行时,另一个表的选择列表列将包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。
  • 交叉联接
    交叉联接将返回左表中的所有行。左表中的每一行均与右表中的所有行组合。交叉联接也称作笛卡尔积。

11.1:使用衍生表

衍生表是指在FROM字句中作为表的SELECT语句。

SELECT DISTINCT s.PurchaseOrderNumber
FROM Sales.SalesOrderHeader s
INNER JOIN ( SELECT SalesOrderID
    FROM Sales.SalesOrderDetail
    WHERE UnitPrice BETWEEN 1000 AND 2000) d ON
    s.SalesOrderID = d.SalesOrderID

11.2:UNION

   将两个或更多查询的结果合并为单个结果集,该结果集包含联合查询中的所有查询的全部行。

下面列出了使用 UNION 合并两个查询结果集的基本规则:

  • 所有查询中的列数和列的顺序必须相同。
  • 数据类型必须兼容。

SELECT ProductModelID, Name FROM Production.ProductModel WHERE ProductModelID NOT IN (3, 4) UNION SELECT ProductModelID, Name FROM dbo.Gloves ORDER BY Name ;

12:TABLESAMPLE

TABLESAMPLE 子句将从 FROM 子句中的表返回的行数限制到样本数或行数的某一百分比。例如:

SELECT FirstName, LastName FROM Person.Person TABLESAMPLE (10 PERCENT) ;

SELECT FirstName, LastName FROM Person.Person TABLESAMPLE (100 ROWS) ;

13:公共表表达式common_table_expression

指定临时命名的结果集,这些结果集称为公用表表达式 (CTE)。该表达式源自简单查询,并且在单条 SELECT、INSERT、UPDATE 或 DELETE 语句的执行范围内定义。该子句也可用在 CREATE VIEW 语句中,作为该语句的 SELECT 定义语句的一部分。公用表表达式可以包括对自身的引用。这种表达式称为递归公用表表达式。

USE AdventureWorks;
GO
WITH DirReps(ManagerID, DirectReports) AS
(
    SELECT ManagerID, COUNT(*)
    FROM HumanResources.Employee AS e
    WHERE ManagerID IS NOT NULL
    GROUP BY ManagerID
)
SELECT ManagerID, DirectReports
FROM DirReps
ORDER BY ManagerID;
GO

SQL笔记1:SELECT及SELECT高级应用的更多相关文章

  1. SQL必知必会 -------- SELECT、注释

    主要是看<SQL必知必会>第四版的书,而写的一些SQL笔记,红色的是方便以后查询的sql语句,工作中主要是使用mysql数据库,所以笔记也是围绕mysql而写的. 下文调试的数据表sql语 ...

  2. SQL Server游标 C# DataTable.Select() 筛选数据 什么是SQL游标? SQL Server数据类型转换方法 LinQ是什么? SQL Server 分页方法汇总

    SQL Server游标   转载自:http://www.cnblogs.com/knowledgesea/p/3699851.html. 什么是游标 结果集,结果集就是select查询之后返回的所 ...

  3. sql: sybase与oracle中insert into select和select into的用法

    1. sybase与oracle中insert into select和select into的用法 http://wjlvivid.iteye.com/blog/1921679 Sybase 一.首 ...

  4. SQL Server中 SET 和 SELECT 赋值有什么区别?

    SQL Server 中对已经定义的变量赋值的方式用两种,分别是 SET 和 SELECT.对于这两种方式的区别,SQL Server 联机丛书中已经有详细的说明,但很多时候我们并没有注意,其实这两种 ...

  5. sql server set赋值和select 赋值的区别以及使用方法

    sqlserver存储过程中SELECT 与 SET 对变量赋值的区别   (备注:虽然变量赋值使用方法已经不是问题,但是,了解一下select和set赋值的区别,还是提高了不少认识.应该有很多人并不 ...

  6. SQL学习(三)Select语句:返回前多少行数据

    在实际工作中,我们可能根据某种排序后,只需要显示前多少条数据,此时就需要根据不同的数据库,使用不同的关键字 一.SQL Server/Access select top 数量/百分比 from tab ...

  7. 你确定 SQL 查询都是以 SELECT 开始的?

    很多 SQL 查询都是以 SELECT 开始的. 不过,最近我跟别人解释什么是窗口函数,我在网上搜索"是否可以对窗口函数返回的结果进行过滤"这个问题,得出的结论是"窗口函 ...

  8. SQL语句之查询(SELECT)

    目录 SQL语句之查询(SELECT) 简单查询 限定查询 模糊查询 排序查询 多表查询 SQL语句之查询(SELECT) SQL是用于访问和处理数据库的标准计算机语言: 中文:结构化查询语言:英文全 ...

  9. SQL 笔记 By 华仔

    -------------------------------------读书笔记------------------------------- 笔记1-徐 最常用的几种备份方法 笔记2-徐 收缩数据 ...

随机推荐

  1. 关于request.getParameterMap()的类型转换和数据获取

    首先po上一个自己写的转换类. /** * @author Xfiler * @described 将request.getParameterMap()转换为普通的Map的工具方法 * @param ...

  2. Tplink客户端设置

    之前在JD上面买了个Tplink,将公司的无线网转成有线的给我的台式机用,可是突然就掉线了,怎么配置都不行.甚至按向导去做了,后来连配置界面都进不去.然后又再某宝上面买了两个,回来配置也发现了这个情况 ...

  3. 异步|同步&阻塞|非阻塞

    异步|同步:区别在于发出一个功能调用时,是否马上得到返回结果 阻塞|非阻塞:区别在于调用结果返回之前,当前线程是否挂起 node.js:单线程.异步非阻塞模型 单线程与异步不矛盾,与并发是矛盾的 ht ...

  4. U盘安装CentOS 7.0

    U盘安装CentOS 7.0 由于学习需要centos环境,so上网下载centos安装镜像,发现版本已经到7.0了,(╮(╯▽╰)╭,上次折腾还是6.4的版本呢,)花了一点时间下载下来按照装6.4的 ...

  5. 【解决】AWS服务控制台中上传文件失败

    使用IE 11,在 AWS Services Console 中不管是 S3 还是 Elastic Beanstalk 的页面中上传页面都会失败,提示信息如下: A problem occurred ...

  6. 字典树的C++实现

    此次代码使用了诸多新鲜玩意,比如自动类型推断,模板类等等,感觉真的超级好玩啊. 自己做了一个简易的测试,程序的健壮性什么的还是比较差的,此程序留待以后进行功能补全. #pragma once #inc ...

  7. XE7 & IOS开发之开发账号(3):证书、AppID、设备、授权profile的申请使用,附Debug真机调试、Ad hoc下iPA文件生成演示(XCode5或以上版本推荐,有图有真相)

    网上能找到的关于Delphi XE系列的移动开发的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 注意,以下讨论都是以&q ...

  8. notepad++与vivado关联

    notepad++与vivado关联 打开vivado软件,选择菜单栏“Tools——>Options…”,在弹出的对话框中,选择General选项卡,如图1所示. 图1  选择General选 ...

  9. IRC常用命令

    From: http://www.blogjava.net/ivanwan/archive/2006/02/17/31296.html IRC命令可以实现一些特殊的功能.目前,亿言堂支持14条IRC命 ...

  10. 如何生成JavaAPI doc

    1         准备工作 1.1    填写完整的注释 对需要生成API的类,填写完整的注释,包括类注释,方法注释,具体格式如下: 类注释: 原先可能author是作者,需要修改成author英文 ...