采纳DISTINCT撤除重复值,SELECT 子查询和 SELECT 联接
分类:博客热点

这里大致的介绍了where条件语句Transact-SQL 语句都足以改用联接表示。其余主题材料只好通过子查询建议。在 Transact-SQL 中,包罗子查询的讲话和语义上等效的不包括子查询的话语在品质上通常没有差距

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

By Gregory Larsen, 二〇一六/01/01 (第贰次宣布于: 二〇一四/052%9卡塔尔(قطر‎

SELECT、INSERT、UPDATE 或 DELETE 语句或其余子查询中的查询。任何允许利用表明式的地点都得以使用子查询。在那示例中,子查询用作 SELECT 语句中名称叫 MaxUnitPrice 的列表明式。

 

有关种类

正文归于进级种类:T-SQL进级:超越底工

追随Gregory 拉尔斯en的T-SQL DML进级种类,其富含了越来越多的高档次和等级方面包车型大巴T-SQL语言,如子查询。

在您开端创办超出基本Transact-SQL语句的更头昏眼花的SQL代码时,您可能会意识供给接受别的SELECT语句的结果来界定查询。 当在父Transact-SQL语句中贮存SELECT语句时,那个嵌入式SELECT语句被称为子查询或相关子查询。 在“抢先底工”楼梯的那么些档期的顺序上,作者将研商三个子查询的不等地点,在今后的三个规模上,小编将切磋有关的子查询。

代码如下复制代码 otherUSE AdventureWorks二零一零Rubicon2;GOSELECT Ord.SalesOrderID, Ord.OrderDate, (SELECT MAX(OrdDet.UnitPrice卡塔尔国 FROM AdventureWorks.Sales.SalesOrderDetail AS OrdDet WHERE Ord.SalesOrderID = OrdDet.SalesOrderID卡塔尔(قطر‎ AS MaxUnitPriceFROM AdventureWorks二零零六奥迪Q72.Sales.SalesOrderHeader AS Ord

本章摘要

什么是子查询?

子查询只是一个SELECT语句,它富含在另一个Transact-SQL语句中。能够在任何能够行使表明式的地点使用子查询。多数子查询重临单个列值,因为它们与相比运算符(=,!=,<,<=,>,> =)或表达式结合使用。当子查询不用作表达式或选拔比较运算符时,它能够回去八个值。别的,子查询以至能够在FROM子句或重大字EXISTS中应用时回来四个列和值。

子查询轻便在Transact-SQL语句中窥见,因为它将是括号中的SELECT语句。由于子查询蕴涵在Transact-SQL语句中,由此子查询普通号称内部查询。而满含子查询的Transact-SQL语句被叫做外部查询。子查询的另四个表征是足以独自于表面查询运维,况兼将无不本地运营,并且可能回到一组行或空行集。

子查询的另一种情势是相关子查询。不过相关的子查询不可能独立于表面包车型客车Transact SQL语句运转。相关子查询利用外界查询中的列或列来约束从相关子查询重临的结果。那对于本文的相关子查询丰裕了。作者将要今后的阶梯随笔中搜求相关的子查询。

使用子查询时还索要思虑以下几点:

  • ntext,text和image数据类型不准从子查询再次回到
  • OPRADODE帕Jero BY子句不能够用来子查询,除非接收TOP操作符
  • 使用子查询的视图无法更改
  • COMPUTE和INTO子句不能够在子查询中动用

子查询也称之为内部查询或内部甄选,而包涵子查询的说话也可以称作外界查询或外部接受。

1:安装AdventureWorks

子查询示例数据示例

为了演示怎么着使用子查询,笔者将索要部分测验数据。 并非创制自个儿的测验数据,我的兼具示例都将运用AdventureWorks二〇〇八Tiguan2数据库。 若是你想跟随并在情形中运行自家的现身说法,那么你能够从今现在处下载AdventureWorks二零一零Evoque2数据库:http://msftdbprodsamples.code...

不少包罗子查询的 Transact-SQL 语句都得以改用联接表示。别的难题只可以通过子查询提出。在 Transact-SQL 中,包蕴子查询的口舌和语义上等效的不满含子查询的言辞在性质上听而不闻没迥然分裂。可是,在部分务必检查存在性的气象中,使用联接会发生更加好的性格。不然,为确定保证清除重复值,必需为外界查询的每一种结果都管理嵌套查询。所以在此些情状下,联接方式会发出更加好的成效。以下示例突显了归来相通结果集的 SELECT 子查询和 SELECT 联接:

2:基本运算符和表明式

回来单个值的子查询的以身作则

看来,在表明式中选拔的子查询或重临相比较运算符一侧的值须求回到单个值。 Transact-SQL语句中有这一个例外之处,供给贰个子询问来回到单个列值,比如在增选列表中WHERE子句等。在本节中,笔者将提供一雨后鞭笋示例,演示如何使用子查询 作为表明式或与比较运算符以满意不相同的事情要求。

代码如下复制代码

3:between

列列表中的子查询

列列表中的子查询是SELECT语句,它回到放置在SELECT子句的列列表中的单个列值。 为了演示如何在接受列表中使用子查询,我们假使大家必得从具有以下职业须求的SELECT语句生成三个结果集:

  • 归来全体Sales.SalesOrderHeader记录有啥有OrderDate等于“二零零六-02-一九零五:00:00.000”
  • 通过SalesOrderID命令归来的笔录
  • 编号每行重临的最旧的各种的RowNumber为1,next oldest的RowNumber为2等
  • 结果集要求多个名字为TotalOrders的列,供给动用极度“二〇〇五-02-壹玖零壹:00:00.000”的OrderDate的总订单数量进行填空

项目清单1中列出了满足那几个必要的代码。

SELECT ROW_NUMBER() OVER (ORDER BY SalesOrderID) RowNumber
      , (SELECT COUNT(*) 
         FROM [Sales].[SalesOrderHeader] 
         WHERE ModifiedDate = '2007-02-19 00:00:00.000') 
                     AS TotalOrders
      , *
FROM [Sales].[SalesOrderHeader]
WHERE OrderDate = '2007-02-19 00:00:00.000';

other/* SELECT statement built using a subquery. */SELECT NameFROM AdventureWorks2008R2.Production.ProductWHERE ListPrice = (SELECT ListPrice FROM AdventureWorks2008R2.Production.Product WHERE Name = 'Chainring Bolts' );

4:like

项目清单1:列列表中的子查询

在此个单一的Transact-SQL语句中,您探访到多个不等的SELECT子句。 子查询是停放在清单1中的语句中间的SELECT语句,它在它周围有括号。 笔者早已去除了子查询语句,并将其放在清单第22中学,防止您想要测量检验以验证它能够单独于全部的Transact-SQL语句运转。

SELECT COUNT(*) 
FROM [Sales].[SalesOrderHeader]
WHERE OrderDate = '2007-02-19 00:00:00.000'

/* SELECT statement built using a join that returns the same result set. */SELECT Prd1. NameFROM AdventureWorks2008R2.Production.Product AS Prd1 JOIN AdventureWorks2008R2.Production.Product AS Prd2 ON (Prd1.ListPrice = Prd2.ListPrice)WHERE Prd2. Name = 'Chainring Bolts';

5:escape

清单2:事项清单第11中学的子查询语句

通过将此子查询列在列列表中,清单1中的此Transact-SQL语句能够对OrderDate为“二零零五-02-1900:00:00.000”的SalesOrderHeader行的数量实行计数,并将该音讯与详细消息一齐回去 有关具备同等OrderDate值的Sales.SalesOrderHeader记录的行音讯。

嵌套在外界 SELECT 语句中的子查询包含以下组件:

6:TOP

WHERE子句中子查询的示范

突发性你想依据SELECT语句的结果来驱动WHERE子句条件。 当您在WHERE子句中的SELECT语句时,此SELECT语句其实是三个子询问。 要言传身教在WHERE子句中使用子查询,若是您供给出示包括购买超(mǎi chāo卡塔尔大型长袖徽标运动衫的Sales.SalesOrderDetail记录。 项目清单3中的代码通过使用子查询来满足自己的突显供给。

SELECT * FROM [Sales].[SalesOrderDetail]
WHERE ProductID = (SELECT ProductID 
                   FROM [Production].[Product]
                    WHERE Name = 'Long-Sleeve Logo Jersey, XL'); 

含蓄常规选取列表组件的正规 SELECT 查询。

7:GROUP BY

清单3:WHERE子句中的子查询

项目清单3中的子查询坐落于WHERE条件的左侧。 此子查询标志Product.Product记录的ProductID,个中产物名字为“Long-Sleeve Logo Jersey,XL”。 此子查询允许作者找到具备与“Long-Sleeve LogoJersey,XL”的成品名称相关联的ProductID的保有Sales.SalesOrderDetail记录。

饱含一个或多少个表或视图名称的健康 FROM 子句。

   7.1:GROUP BY ALL

使用子查询来支配TOP条目的上行下效

采纳TOP子句再次回到的行数能够由表明式调节。 清单5中的代码标记了相应依据TOP子句中的子查询重返的Sales.SalesOrderDetail行的数量。

SELECT TOP (SELECT TOP 1 OrderQty 
            FROM [Sales].[SalesOrderDetail]
            ORDER BY ModifiedDate) *  
FROM [Sales].[SalesOrderDetail]
WHERE ProductID = 716;

可选的 WHERE 子句。

   7.2:HAVING

项目清单4:TOP子句中的子查询

清单4中的代码应用从子查询再次来到的OrderQty值来标志就要TOP子句中利用的值。 通过使用子查询来调控TOP子句重回的行数,能够创设多个子询问,以便在运维时动态地辨别从询问重回的行数。

可选的 GROUP BY 子句。

8:SELECT字句技能

子条目示例

为了演示在HAVING子句中使用子查询,借使您抱有以下专业须求:

变化包罗Sales.SalesOrderHeader.OrderDate和每种日期的订单数量的结果集,在那之中订单数量超过“二零零五-05-01”上实践的订单数量。

为了满意那么些必要,小编付出了清单6中利用HAVING子句中的子查询的查询。

SELECT count(*), OrderDate 
FROM [Sales].[SalesOrderHeader]
GROUP BY OrderDate
HAVING count(*) >
       (SELECT count(*) 
        FROM [Sales].[SalesOrderHeader]
        WHERE OrderDate = '2006-05-01 00:00:00.000');

可选的 HAVING 子句。

   8.1:使用DISTINCT清除重复值

清单5:HAVING子句中的子查询

项目清单5中的代码具备HAVING子句侧边的子查询,并在自个儿的子查询中使用COUNT函数来明显“2005-05-01”上的订单数量。

子查询的 SELECT 查询总是利用圆括号括起来。它无法富含 COMPUTE 或 FOR BROWSE 子句,假使同一时候钦赐了 TOP 子句,则只可以分包 O凯雷德DE昂科雷 BY 子句。

   8.2:再次来到拼接的结果

在函数调用中使用子查询的躬行推行

要自己要作为典范听从规则在函数调用中使用子查询,假若您需求显示OrderDate和种种Sales.SalesOrderHeader记录的最大OrderDate之间的运气。 项目清单6中的代码切合此要求。

SELECT SalesOrderID
      , OrderDate
      ,DATEDIFF
          (
            dd,OrderDate
        ,(SELECT MAX(OrderDate)
          FROM [Sales].[SalesOrderHeader])
          ) AS DaysBetweenOrders
         ,(SELECT MAX(OrderDate)
        FROM [Sales].[SalesOrderHeader]) 
            AS MaxOrderDate
FROM [Sales].[SalesOrderHeader];

子查询能够嵌套在外表 SELECT、INSERT、UPDATE 或 DELETE 语句的 WHERE 或 HAVING 子句内,也得以嵌套在别的子查询内。即便依据可用内部存储器和询问中别的表明式的复杂程度的不等,嵌套约束也不完全同样,但嵌套到 32 层是只怕的。个别查询只怕不帮忙 32 层嵌套。任何能够应用表明式的地点都得以使用子查询,只要它回到的是单个值。

   8.3使用INTO字句

项目清单6:函数调用中的子查询

项目清单6中的代码有多个不等的子查询。 几个子查询重回Sales.SalesOrderHeader表中的最大OrderDate。 不过率先个头查询用于将日期传递给DATEDIFF函数的第3个参数。

倘使有个别表只出未来子查询中,而从未出以往表面查询中,那么该表中的列就不可能满含在出口中。

9:子查询

重临多少个值的子查询的演示

小编现今的具有示例都带有仅在单个列中重回单个值的子查询。 并非具备的子查询都有其一须要。 接下来的几个例证将动用再次回到七个值和/或七个列的子查询。

包蕴子查询的语句平日采取以下格式中的一种:

   9.1:子查询类型

FROM子句中的子查询示例

在FROM子句中,平日会标志您的Transact-SQL语句将对其实施的表或表的集纳。 每种表提供一组记录,您的查询将用来分明询问的末段结出集。 子查询能够被以为是回来一组记录的查询,因而它能够像FROM表相近在FROM子句中运用。 清单7中的查询突显了自家怎么着在FROM子句中使用子查询。 当在FROM子句中使用子查询时,从子查询生成的结果集经常堪当派生表。

SELECT SalesOrderID 
FROM (SELECT TOP 10 SalesOrderID 
      FROM [Sales].[SalesOrderDetail]
      WHERE ProductID = 716
      ORDER BY ModifiedDate DESC) AS Last10SalesOrders;

代码如下复制代码

   9.2:替代表明式的询问

事项清单7:FROM子句中的子查询
  • 事项清单7中的代码应用FROM子句中的子查询来创设一个名字为Last10SalesOrders的表外号。 笔者的子查询重回包括ProductID为716的终极11个Sales.alesOrderDetail记录。
  • 项目清单7中的代码是三个特轻巧的事例,表明怎么样在FROM子句中使用子查询。 通过在FROM子句中使用子查询,您能够轻便地营造更目迷五色的FROM语法,该语法将子查询的结果与其余表或别的子查询相结合,如清单8所示。
    SELECT DISTINCT OrderDate
    FROM (SELECT TOP 10 SalesOrderID 
          FROM [Sales].[SalesOrderDetail]
          WHERE ProductID = 716
          ORDER BY ModifiedDate DESC) AS Last10SalesOrders
    JOIN [Sales].[SalesOrderHeader] AS SalesOrderHeader
    ON Last10SalesOrders.SalesOrderID = SalesOrderHeader.SalesOrderID
    ORDER BY OrderDate

WHERE expression [NOT] IN (subquery)

  9.3:多层嵌套
项目清单8:使用实际表连接派生表

在清单第88中学,作者看齐了作者在项目清单7中开创的子查询/派生表,并将其与SalesOrderHeader表相加。 通过那样做,小编得以明确最终十二回订购ProductID = 716的OrderDate。

WHERE expression comparison_operator [ANY | ALL] (subquery)

10:相比使用 EXISTS 和 IN 的询问

利用具备IN关键字的子查询的示范

你能够编写制定一个赶回列的多少个值的子查询的地点是当您的子查询生成与IN关键字一同行使的笔录集时。 项目清单9中的代码演示了哪些使用子查询将值传递给IN关键字。

SELECT * FROM [Sales].[SalesOrderDetail] 
WHERE ProductID IN 
        (SELECT ProductID 
         FROM [Production].[Product]
         WHERE Name like '%XL%');

WHERE [NOT] EXISTS (subquery)

11:联接

  11.1:使用衍生表
清单9:使用子查询将值传递给IN关键字

清单9中的代码应用三个子询问从Product.Product表中回到分化的ProductID值,其名目富含字符“XL”。 然后在IN关键字中接纳从子查询重回的那个ProductID值来节制从Sales.SalesOrderDetail表再次回到哪些行。

   11.2:UNION

在改造数据的话语中使用子查询的示范

到近年来甘休,小编的具备示例向来在示范怎么着在SELECT语句的差异部分中使用子查询。 也得以在INSERT,UPDATE或DELETE语句中使用子查询。 清单10中的代码显示了怎么样在INSERT语句中使用子查询。

DECLARE @SQTable TABLE (
OrderID int,
OrderDate datetime,
TotalDue money,
MaxOrderDate datetime);

-- INSERT with SubQuery
INSERT INTO @SQTable 
   SELECT SalesOrderID,
          OrderDate, 
          TotalDue, 
          (SELECT MAX(OrderDate) 
           FROM [Sales].[SalesOrderHeader]) 
   FROM [Sales].[SalesOrderHeader]
   WHERE CustomerID = 29614;

-- Display Records
SELECT * FROM @SQtable;

12:TABLESAMPLE

清单10:INSERT语句中的子查询

在清单第10中学的代码中,作者使用二个子询问来计量要插入列MaxOrderDate的值。 这只是在INSERT语句中什么使用子查询的一个示范。 请记住,也足以在UPDATE和/或DELETE语句中使用子查询。

13:公共表表明式common_table_expression

子查询和JOIN之间的习性考虑

假使您已阅读由Microsoft生成的“子查询根基知识”文书档案(http://technet.microsoft.com/....aspx卡塔尔),那么你或然曾在那语句中运维包含子查询的言辞的属性:

“在Transact-SQL中,满含子查询的口舌和不享有语义相同的版本的言辞常常未有品质差距。

要将使用子查询的查询的习性与不使用子查询的一致查询举行比较,小编就要项目清单3中重写本身的子查询以应用JOIN操作。 项目清单11展现了本身重写的JOIN查询,也正是清单3中的查询。

SELECT SOD.* 
FROM [Sales].[SalesOrderDetail] AS SOD
INNER JOIN 
[Production].[Product] AS P
ON SOD.ProductID = P.ProductID
WHERE P.Name = 'Long-Sleeve Logo Jersey, XL';

 

清单11:与清单3中的查询格外的JOIN查询

要比较使用子查询的清单3中的查询的属性和采取JOIN的清单1第11中学的查询,我将接受项目清单1第22中学的代码运转五个查询。

SET STATISTICS IO ON;
SET STATISTICS TIME ON;

-- Listing 3 query
SELECT * FROM [Sales].[SalesOrderDetail]
WHERE ProductID = (SELECT ProductID 
                   FROM Production.Product
                    WHERE Name = 'Long-Sleeve Logo Jersey, XL'); 

-- Listing 11 query
SELECT SOD.* 
FROM [Sales].[SalesOrderDetail] AS SOD
INNER JOIN 
[Production].[Product] AS P
ON SOD.ProductID = P.ProductID
WHERE P.Name = 'Long-Sleeve Logo Jersey, XL';

1:安装AdventureWorks

项目清单12:测量试验清单3和项目清单4的习性代码

在运营列表1第22中学的代码之后,笔者回想了“SET STATISTICS”语句生成的新闻。 通过翻看总括音信,作者开采那八个查询对SalesOrderDetail表都有3,309个逻辑读取,对于Product表有七个逻辑读取,每一个使用31 ms的CPU。 其它小编翻看了SQL Server为那七个查询创造的进行布署。 作者发觉SQL Server为两个生成了同一的推行布置。 由此,对于自身的景况使用子查询或JOIN查询产生了平等的习性,正如微软所记录的那么。

     本连串笔记均遵照AdventureWorks数据库,有关AdventureWorks的装置支持如下:

总结

子查询是放到另二个Transact-SQL语句的SELECT语句。子查询能够独立于表面查询运营,由此有的时候也称为独立查询。记住,任什么时候候你有三个子查询代替多个表明式,或然与比较运算符一齐行使,它只可以回去一个列和值。常常能够运用JOIN逻辑重写子查询。子查询是帮忙您营造更复杂的Transact-SQL语句以满足职业必要的兵不血刃工具。

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

主题素材和答案

在本节中,您可以通过回答以下难题来查看您使用子查询概念理解的开始和结果。

    浏览到文件 instawdb.sql,并单击“打开”。该公文的暗中认可地点为 C:Program FilesMicrosoft SQL Server90ToolsSamplesAdventureWorks OLTP。

问题1:

变成那个句子“叁个子询问是另贰个Transact-SQL语句中的SELECT语句,_____________________”。

  • 不能够独立于完全的查询运维。
  • 引用来自外界查询的列。
  • 当独立于表面查询运维时,它将回到结果。

    运转脚本此前,在剧本中找到语句 SET @data_path = @sql_path + 'AWDB';,并改换该语句使其指向 instawdb.sql 脚本之处。譬如,SET @data_path = 'C:Program FilesMicrosoft SQL Server90ToolsSamplesAdventureWorks OLTP';

问题2:

哪些时候子查询只要求八个列和值手艺再次回到(选取具有适用的)?

  • 当子查询用于FROM子句时
  • 当IN子句中使用子查询时
  • 当表明式中使用子查询时
  • 当子查询与相比运算符一齐行使时

    实施脚本。

问题3:

在WHERE子句中接受多个子询问的Transact-SQL语句总是比不包含子查询(True或False)的相通查询推行得慢。

 

回答:

2:基本运算符和表达式

问题1:

无可争辩的答案是c。子查询能够独立于外界查询运转,并重返结果。它无需来自外界查询的任何列,假若它有来自外界查询的列,它将被叫做相关子查询。

运算符 描述
!=
!>
!<
<
<=
<>
=
>
>=
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 是等效的

问题2:

科学的答案是c和d。当作为表明式或在相比操作中时,子查询须要再次来到多个列值。当子查询与IN关键字一同利用时,它可以回来列的单个或多少个值。假若在FROM子句中使用子查询,它必须要回到一列和二个值,但也得以回来多少个列和值。

 

问题3:

没有错答案是荒唐的。 SQL Server优化器非常聪明,很可能为七个等效查询计算同一的实施安顿。固然包括子查询的查询的施行布置和还未有子查询的查询的实践布置最后都抱有同等的施行陈设,则七个查询将兼具同样的脾性。

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 行受影响State of Qatar

   

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 行受影响State of Qatar

    表明,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:子查询类型

     能够在多数地方钦赐子查询(必需全方位精晓):

  • 利用别称。有关详细音讯,请参阅利用外号的子查询.aspx)。
  • 动用 IN 或 NOT IN。有关详细消息,请参阅利用 IN 的子查询.aspx)和行使 NOT IN 的子查询.aspx)。
  • 在 UPDATE、DELETE 和 INSERT 语句中。有关详细消息,请参阅 UPDATE、DELETE 和 INSERT 语句中的子查询.aspx)。
  • 接纳相比运算符。有关详细新闻,请参阅使用相比运算符的子查询.aspx)。
  • 运用 ANY、SOME 或 ALL。有关详细消息,请参阅用 ANY、SOME 或 ALL 修正的相比较运算符.aspx)。
  • 动用 EXISTS 或 NOT EXISTS。有关详细音信,请参阅动用 EXISTS 的子查询.aspx)和利用 NOT EXISTS 的子查询.aspx)。
  • 替代表明式。有关详细新闻,请参阅用来替代表明式的子查询威尼斯正规官网,.aspx)。

9.2:替代表明式的询问

     必得主要说说代表表达式的子查询。在 Transact-SQL 中,除了在 O奥迪Q7DE大切诺基 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,第4个查询利用 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 OUTE奥迪Q3子句中内定的左表的保有行,而不只是联接列所相称的行。即使左表的某一行在右表中绝非相配行,则在提到的结果集行中,来自右表的装有接收列表列均为空值。
    • RIGHT JOIN 或 RIGHT OUTER JOIN
      右向外部联接是左向外界联接的反向联接。将回来右表的装有行。假使右表的某一行在左表中平昔不相配行,则将为左表再次回到空值。
    • FULL JOIN 或 FULL OUTER JOIN
      完全外部联接将回来左表和右表中的全部行。当某一行在另一个表中未有相称行时,另叁个表的抉择列表列将含有空值。要是表之间有相称行,则整个结果集行满含基表的数据值。
  • 穿插联接
    穿插联接将赶回左表中的全体行。左表中的每一行均与右表中的全部行组合。交叉联接也称作笛Carl积。

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

本文由威尼斯在线注册平台发布于博客热点,转载请注明出处:采纳DISTINCT撤除重复值,SELECT 子查询和 SELECT 联接

上一篇:威尼斯正规官网页面之间无法传递变量 下一篇:没有了
猜你喜欢
热门排行
精彩图文