SQL笔记1:SELECT及SELECT高级应用
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:子查询类型
可以在许多位置指定子查询(必须全部掌握):
- 使用别名。有关详细信息,请参阅使用别名的子查询。
- 使用 IN 或 NOT IN。有关详细信息,请参阅使用 IN 的子查询和使用 NOT IN 的子查询。
- 在 UPDATE、DELETE 和 INSERT 语句中。有关详细信息,请参阅 UPDATE、DELETE 和 INSERT 语句中的子查询。
- 使用比较运算符。有关详细信息,请参阅使用比较运算符的子查询。
- 使用 ANY、SOME 或 ALL。有关详细信息,请参阅用 ANY、SOME 或 ALL 修改的比较运算符。
- 使用 EXISTS 或 NOT EXISTS。有关详细信息,请参阅使用 EXISTS 的子查询和使用 NOT EXISTS 的子查询。
- 代替表达式。有关详细信息,请参阅用于替代表达式的子查询。
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 进行隐式转换的类型。
联接可分为以下几类:
- 内部联接(典型的联接运算,使用类似于 = 或 <> 的比较运算符)。内部联接包括同等联接和自然联接。
内部联接使用比较运算符根据每个表的通用列中的值匹配两个表中的行。例如,检索 students 和 courses 表中学生标识号相同的所有行。 - 外部联接。外部联接可以是左向外部联接、右向外部联接或完整外部联接。
在 FROM 子句中可以用下列某一组关键字来指定外部联接:- LEFT JOIN 或 LEFT OUTER JOIN。
左向外部联接的结果集包括 LEFT OUTER 子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某一行在右表中没有匹配行,则在关联的结果集行中,来自右表的所有选择列表列均为空值。 - RIGHT JOIN 或 RIGHT OUTER JOIN
右向外部联接是左向外部联接的反向联接。将返回右表的所有行。如果右表的某一行在左表中没有匹配行,则将为左表返回空值。 - FULL JOIN 或 FULL OUTER JOIN
完整外部联接将返回左表和右表中的所有行。当某一行在另一个表中没有匹配行时,另一个表的选择列表列将包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。
- LEFT JOIN 或 LEFT 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高级应用的更多相关文章
- SQL必知必会 -------- SELECT、注释
主要是看<SQL必知必会>第四版的书,而写的一些SQL笔记,红色的是方便以后查询的sql语句,工作中主要是使用mysql数据库,所以笔记也是围绕mysql而写的. 下文调试的数据表sql语 ...
- SQL Server游标 C# DataTable.Select() 筛选数据 什么是SQL游标? SQL Server数据类型转换方法 LinQ是什么? SQL Server 分页方法汇总
SQL Server游标 转载自:http://www.cnblogs.com/knowledgesea/p/3699851.html. 什么是游标 结果集,结果集就是select查询之后返回的所 ...
- sql: sybase与oracle中insert into select和select into的用法
1. sybase与oracle中insert into select和select into的用法 http://wjlvivid.iteye.com/blog/1921679 Sybase 一.首 ...
- SQL Server中 SET 和 SELECT 赋值有什么区别?
SQL Server 中对已经定义的变量赋值的方式用两种,分别是 SET 和 SELECT.对于这两种方式的区别,SQL Server 联机丛书中已经有详细的说明,但很多时候我们并没有注意,其实这两种 ...
- sql server set赋值和select 赋值的区别以及使用方法
sqlserver存储过程中SELECT 与 SET 对变量赋值的区别 (备注:虽然变量赋值使用方法已经不是问题,但是,了解一下select和set赋值的区别,还是提高了不少认识.应该有很多人并不 ...
- SQL学习(三)Select语句:返回前多少行数据
在实际工作中,我们可能根据某种排序后,只需要显示前多少条数据,此时就需要根据不同的数据库,使用不同的关键字 一.SQL Server/Access select top 数量/百分比 from tab ...
- 你确定 SQL 查询都是以 SELECT 开始的?
很多 SQL 查询都是以 SELECT 开始的. 不过,最近我跟别人解释什么是窗口函数,我在网上搜索"是否可以对窗口函数返回的结果进行过滤"这个问题,得出的结论是"窗口函 ...
- SQL语句之查询(SELECT)
目录 SQL语句之查询(SELECT) 简单查询 限定查询 模糊查询 排序查询 多表查询 SQL语句之查询(SELECT) SQL是用于访问和处理数据库的标准计算机语言: 中文:结构化查询语言:英文全 ...
- SQL 笔记 By 华仔
-------------------------------------读书笔记------------------------------- 笔记1-徐 最常用的几种备份方法 笔记2-徐 收缩数据 ...
随机推荐
- python---psutil
系统性能信息模块psutil psutil是一个跨平台库,能够轻松实现获取系统运行的进程和系统利用率(CPU,内存,磁盘,网络等)信息,主要应用于系统监控,分析和限制系统资源及进程的管理,它实现了同等 ...
- ashx文件不能使用DAL和Model的解决办法
好久没有写web程序了,今天在写web程序时,发现一个问题,在ashx文件中,已经using了DAL和Model命名空间,而且引用中也引用了程序集,可是还报错:未能找到类型或命名空间"Mod ...
- oracle like模糊查询
简单的方式,使用"%" 和 "_" 字符匹配操作可以使用通配符 "%" 和 "_": %:表示任意个字符,包括零个: _ ...
- C# 抽象类abstract
不能初始化的类被叫做抽象类,它们只提供部分实现,但是另一个类可以继承它并且能创建它们的实例,有未被实现的方法.抽象类不可以new对象. "一个包含一个或多个纯虚函数的类叫抽象类,抽象类不能被 ...
- Ubuntu16.10 主题flatabulous安装
以前通过apt直接安装的flatabulous主题16.10上安装会出现找不到包的情况,可以采用源码安装 原来的apt-get方式: 1:主题 sudo add-apt-repository ppa: ...
- d3安装异常
使用npm安装D3,发现其工程名和依赖名重复,导致安装异常 http://thisdavej.com/node-newbie-error-npm-refusing-to-install-package ...
- jquery mobile button样式设置
<a href="#" class="ui-btn">提交</a> ui-btn表示按钮样式 ui-btn-a,ui-btn-b:the ...
- 【原】redis插件安装
wget -c https://github.com/nicolasff/phpredis/archive/2.2.4.tar.gz -O phpredis-2.2.4.tar.gz tar xzf ...
- 对想进入Unity开发新人的一些建议
提前声明:本文只是写给那些非职业游戏开发人士,只面向那些在校本科生,或已就业但无unity背景的同学们,当然是面对程序员方向的.本人刚工作也没多久,资历尚浅,之前在网上有一位同学让我谈谈一些想法,所以 ...
- .net操作数据库,史上最牛逼的方法,你见过这种方法吗
免费分享给大家.下载地址在最下面. C# code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ...