zoukankan      html  css  js  c++  java
  • Sql Server系列:嵌套查询

      嵌套查询是指一个查询语句嵌套在另一个查询语句内部的查询。嵌套查询也就子查询,在SELECT子句中先计算子查询,子查询结果作为外层另一个查询的过滤条件,查询可以基于一个表或多个表。子查询中可以使用比较运算符,如“<”、“<=”、“>”、“>=”等。

      子查询中常用的操作符有ANY(SOME)、ALL、EXISTS。子查询可以添加到SELECT 、UPDATE和DELETE语句中,可以进行多层嵌套。

    1 使用比较运算符

      子查询使用比较运算符,如“<”、“<=”、“>”、“>=”等。

      示例:返回单个值的SELECT语句的嵌套查询

    SELECT * FROM [dbo].[Product]
    WHERE [UnitPrice] = (
        SELECT MIN([UnitPrice]) FROM [dbo].[Product]
    )
    SELECT * FROM [dbo].[Product]
    WHERE [CategoryID] = 
    ( SELECT [CategoryID] FROM [dbo].[Category] WHERE [CategoryName] = 'LINQ to SQL' )

    2. 使用IN关键字

      IN关键字进行子查询时,内层查询语句仅仅返回一个数据列,这个数据列里的值将提供给外层查询语句进行比较。

      示例:返回多个值的子查询的嵌套查询

    SELECT * FROM [dbo].[Product]
    WHERE [CategoryID] IN (
        SELECT [CategoryID] FROM [dbo].[Category] WHERE [CategoryID] <= 10
    )

      尽管使用IN的嵌套查询方式可以实现,但更好的方式是使用内连接实现这种查询,而不是使用使用嵌套的SELECT。

      上例的子查询使用INNER JOIN方式:

    SELECT [dbo].[Product].* FROM [dbo].[Product]
    INNER JOIN [dbo].[Category]
        ON [dbo].[Product].[CategoryID] = [dbo].[Category].[CategoryID]
    WHERE [dbo].[Category].[CategoryID] <= 10

      出于性能方面的考虑,如果没有特别的理由要使用嵌套的SELECT,则还是应使用连接方式作为默认的解决方案。在大部分情况下,SQL Server会将嵌套子查询解决方案解析为和使用连接用于的查询计划,在检查嵌套子查询和内连接查询计划时,会发现它们的完全相同的计划。大多数情况下,这两种方法没有多大的区别。当查询计划不同时,连接通常的更好的选择。

      SELECT语句中可以使用NOT IN运算符,其作用与IN相反。

    3. ANY、SOME关键字

      ANY和SOME关键字是同义词,表示满足其中任一条街。它们允许创建一个表达式对子查询的返回值列表进行比较,只要满足内层子查询中任何一个比较条件,就返回一个结果作为外层查询的条件。

      ANY关键字接在一个比较操作符的后面,表示与子查询返回的任何值比较为TRUE,则返回TRUE。

      示例:

    IF 20 > ANY ( SELECT [UnitsInStock] FROM [dbo].[Product] )
        PRINT '1'
    ELSE
        PRINT '0'

    4. ALL关键字

      ALL关键字用于需要同时满足所有内层查询的条件,只有当子查询返回的所有值比较都为TRUE,才返回TRUE。

      示例:

    IF 20 > ALL ( SELECT [UnitsInStock] FROM [dbo].[Product] )
        PRINT '1'
    ELSE
        PRINT '0'

    5. EXISTS关键字

      EXISTS关键字后面的参数是一个任意的子查询,系统对子查询进行运算以判断它是否返回行,如果至少返回一行,则EXISTS的结果为TRUE,此时外层查询语句将进行查询;如果子查询没有返回任何行,那么EXISTS返回的结果是FALSE,此时外层语句将不进行查询。

      示例:

    SELECT * FROM [dbo].[Category]
    WHERE EXISTS (
        SELECT * FROM [dbo].[Product]
        WHERE [CategoryID] = 1
    )

      EXISTS关键字还可以和条件表达式一起使用。

    SELECT * FROM [dbo].[Category]
    WHERE [CategoryName] ='LINQ to SQL'
    AND EXISTS (
        SELECT * FROM [dbo].[Product]
        WHERE [CategoryID] = 1
    )

      NOT EXISTS与EXISTS使用方法相同,返回的结果相反。

    SELECT * FROM [dbo].[Category]
    WHERE NOT EXISTS (
        SELECT * FROM [dbo].[Product]
        WHERE [CategoryID] = 1
    )

      Exists关联子查询:查询所有存在Product的Category

    SELECT * FROM [dbo].[Category] c
    WHERE EXISTS (
        SELECT * FROM [dbo].[Product] p
        WHERE p.[CategoryID] = c.[CategoryID]
    )

      上例同样可以使用INNER JOIN实现:

    SELECT c.* FROM [dbo].[Category] c
    INNER JOIN [dbo].[Product] p
        ON p.[CategoryID] = c.[CategoryID]

      基于连接的语法可以得到相同的结果,但使用EXISTS具有更好的性能。使用EXISTS关键字,SQL Server不需要执行一行一行的完全连接,而是直接寻找记录,直到找到第一个匹配的记录。

  • 相关阅读:
    教你写Makefile(很全,含有工作经验的)
    configure.in详解
    使用autoconf与automake自动生成MakeFile文件
    例解 autoconf 和 automake 生成 Makefile 文件
    MYSQL:SQL中Group By的使用
    日志文件系统syslog,syslog-ng
    syslog-ng应用详解
    sublime的lua插件
    MySQL索引类型
    linux下automake用法
  • 原文地址:https://www.cnblogs.com/libingql/p/4134298.html
Copyright © 2011-2022 走看看