SQL Server的子查询
子查询是嵌套在SELECT、INSERT、UPDATE、DELETE语句中或另一个子查询中的查询。
可以在允许表达式的任何位置使用子查询。
示例:
USE AdventureWorks2016;
GO
SELECT Ord.SalesOrderID, Ord.OrderDate,
(SELECT MAX(OrdDet.UnitPrice)
FROM Sales.SalesOrderDetail AS OrdDet
WHERE Ord.SalesOrderID = OrdDet.SalesOrderID) AS MaxUnitPrice
FROM Sales.SalesOrderHeader AS Ord;
GO

子查询也称为内部查询或内部选择,而包含子查询的语句也称为外部查询或外部选择。
许多包含子查询的 Transact-SQL 语句也可以表述为联接。其他问题只能用子查询提出。在 Transact-SQL 中,包含子查询的语句与不包含子查询的语义等效版本之间通常没有性能差异。但是,在某些必须检查是否存在的情况下,联接会产生更好的性能。否则,必须为外部查询的每个结果处理嵌套查询,以确保消除重复项。在这种情况下,联接方法将产生更好的结果。
以下示例显示了返回相同结果集和执行计划的子查询和联接:
USE AdventureWorks2016;
GO
/* SELECT statement built using a subquery. */
SELECT [Name]
FROM Production.Product
WHERE ListPrice =
(SELECT ListPrice
FROM Production.Product
WHERE [Name] = 'Chainring Bolts' );
GO
/* SELECT statement built using a join that returns
the same result set. */
SELECT Prd1.[Name]
FROM Production.Product AS Prd1
JOIN Production.Product AS Prd2
ON (Prd1.ListPrice = Prd2.ListPrice)
WHERE Prd2.[Name] = 'Chainring Bolts';
GO
嵌套在外部 SELECT 语句中的子查询具有以下组件:
子查询的 SELECT 查询始终括在括号中。它不能包含 or 子句,并且只能在还指定 TOP 子句时才包含子句。
子查询可以嵌套在外部 WHERE、HAVING、SELECT、INSERT、UPDATE、DELETE或语句的 or 子句中,也可以嵌套在另一个子查询中。最多可以嵌套 32 个级别,但限制因可用内存和查询中其他表达式的复杂性而异。单个查询可能不支持嵌套多达 32 个级别。如果子查询返回单个值,则子查询可以出现在可以使用表达式的任何位置。
如果表仅出现在子查询中而不出现在外部查询中,则该表中的列不能包含在输出(外部查询的选择列表)中。
包含子查询的语句通常采用以下格式之一:
在某些 Transact-SQL 语句中,可以像计算独立查询一样计算子查询。从概念上讲,子查询结果被替换到外部查询中(尽管这不一定是 SQL Server 实际处理带有子查询的 Transact-SQL 语句的方式)。
有三种基本类型的子查询:
示例:外部查询子句中的 BusinessEntityID 列由外部查询子句 (Sales.Store) 中的表名隐式限定。子查询的选择列表中对 CustomerID 的引用由子查询子句(即 Sales.Customer 表)限定。
USE AdventureWorks2016;
GO
SELECT [Name]
FROM Sales.Store
WHERE BusinessEntityID NOT IN
(SELECT CustomerID
FROM Sales.Customer
WHERE TerritoryID = 5);
GO
一般,语句中的列名由同一级别的子句中引用的表隐式限定。如果子查询子句中引用的表中不存在列,则外部查询子句中引用的表将隐式限定该列。
下面是指定这些隐式假设的查询的外观:
USE AdventureWorks2016;
GO
SELECT [Name]
FROM Sales.Store
WHERE Sales.Store.BusinessEntityID NOT IN
(SELECT Sales.Customer.CustomerID
FROM Sales.Customer
WHERE TerritoryID = 5);
GO
显式声明表名永远不会错,并且始终可以使用显式限定覆盖有关表名的隐式假设。
子查询本身可以包含一个或多个子查询。任意数量的子查询可以嵌套在一个语句中。
示例:查询查找同时也是销售人员的员工的姓名。
USE AdventureWorks2016;
GO
SELECT LastName, FirstName
FROM Person.Person
WHERE BusinessEntityID IN
(SELECT BusinessEntityID
FROM HumanResources.Employee
WHERE BusinessEntityID IN
(SELECT BusinessEntityID
FROM Sales.SalesPerson)
);
GO
输出:
LastName FirstName
-------------------------------------------------- -----------------------
Jiang Stephen
Abbas Syed
Alberts Amy
Ansman-Wolfe Pamela
Campbell David
Carson Jillian
Ito Shu
Mitchell Linda
Reiter Tsvi
Saraiva Jos
Vargas Garrett
Varkey Chudukatil Ranjit
Valdez Rachel
Tsoflias Lynn
Pak Jae
Blythe Michael
Mensa-Annan Tete
(17 row(s) affected)
最里面的查询返回销售人员 ID。下一个更高级别查询使用这些销售人员 ID 进行评估,并返回员工的联系人 ID 号。最后,外部查询使用联系人 ID 查找员工的姓名。
还可以将此查询表示为联接:
USE AdventureWorks2016;
GO
SELECT LastName, FirstName
FROM Person.Person c
INNER JOIN HumanResources.Employee e
ON c.BusinessEntityID = e.BusinessEntityID
JOIN Sales.SalesPerson s
ON e.BusinessEntityID = s.BusinessEntityID;
GO
可以通过执行一次子查询并将结果值替换到外部查询的子句中来计算许多查询。在包含相关子查询(也称为重复子查询)的查询中,子查询依赖于其值的外部查询。这意味着子查询将重复执行,外部查询可能选择的每一行执行一次。
示例:
USE AdventureWorks2016;
GO
SELECT DISTINCT c.LastName, c.FirstName, e.BusinessEntityID
FROM Person.Person AS c JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = c.BusinessEntityID
WHERE 5000.00 IN
(SELECT Bonus
FROM Sales.SalesPerson sp
WHERE e.BusinessEntityID = sp.BusinessEntityID) ;
GO
输出结果:
LastName FirstName BusinessEntityID
-------------------------- ---------- ------------
Ansman-Wolfe Pamela 280
Saraiva José 282
(2 row(s) affected)
此语句中的上一个子查询不能独立于外部查询进行计算。它需要 Employee.BusinessEntityID 的值,但此值会随着 SQL Server 检查 Employee 中的不同行而更改。 这正是计算此查询的方式:SQL Server 通过将每行中的值替换为内部查询来考虑将 Employee 表的每一行包含在结果中。 例如,如果 SQL Server 首先检查 的行,则变量 Employee.BusinessEntityID 采用值 285,SQL Server 将其替换到内部查询中。这两个查询示例表示具有相关子查询的前一个示例的分解。
USE AdventureWorks2016;
GO
SELECT Bonus
FROM Sales.SalesPerson
WHERE BusinessEntityID = 285;
GO
结果为 0.00(没有收到奖金,因为他们不是销售人员),因此外部查询的计算结果为:
USE AdventureWorks2016;
GO
SELECT LastName, FirstName
FROM Person.Person AS c JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = c.BusinessEntityID
WHERE 5000 IN (0.00);
GO
由于这是 false,因此 的行不包含在具有相关子查询的上一个示例查询的结果中。对 的行执行相同的过程。您将看到此行包含在结果中,因为包含结果。
小结:相关子查询还可以通过在外部查询中引用表中的列作为表值函数的参数,在子句中包含表值函数。在这种情况下,对于外部查询的每一行,将根据子查询计算表值函数。
如果在子查询中引用的列在子查询中不存在,但存在于外部查询的子句引用的表中,则查询将执行而不会出错。SQL Server 使用外部查询中的表名隐式限定子查询中的列。

我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr
我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时
我在Rails上使用带有ruby的solr。一切正常,我只需要知道是否有任何现有代码来清理用户输入,比如以?开头的查询。或* 最佳答案 我不知道执行此操作的任何代码,但理论上可以通过查看parsingcodeinLucene来完成并搜索thrownewParseException(只有16个匹配!)。在实践中,我认为您最好只捕获代码中的任何solr异常并显示“无效查询”消息或类似信息。编辑:这里有几个“sanitizer”:http://pivotallabs.com/users/zach/blog/articles/937-s
我正在为锦标赛开发一个Rails应用程序。我在这个查询中使用了三个模型:classPlayertruehas_and_belongs_to_many:tournamentsclassTournament:destroyclassPlayerMatch"Player",:foreign_key=>"player_one"belongs_to:player_two,:class_name=>"Player",:foreign_key=>"player_two"在tournaments_controller的显示操作中,我调用以下查询:Tournament.where(:id=>params
我想用sunspot重现以下原始solr查询q=exact_term_text:fooORterm_textv:foo*ORalternate_text:bar*但我无法通过标准的太阳黑子界面理解这是否可能以及如何实现,因为看起来:fulltext方法似乎不接受多个文本/搜索字段参数我不知道将什么参数作为第一个参数传递给fulltext,就好像我通过了"foo"或"bar"结果不匹配如果我传递一个空参数,我得到一个q=*:*范围过滤器(例如with(:term).starting_with('foo*')(顾名思义)作为过滤器查询应用,因此不参与评分。似乎可以手动编写字符串(或者可能使
例如,假设我有一个名为Products的模型,并且在ProductsController中,我有以下代码用于product_listView以显示已排序的产品。@products=Product.order(params[:order_by])让我们想象一下,在product_listView中,用户可以使用下拉菜单按价格、评级、重量等进行排序。数据库中的产品不会经常更改。我很难理解的是,每次用户选择新的order_by过滤器时,rails是否必须查询,或者rails是否能够以某种方式缓存事件记录以在服务器端重新排序?有没有一种方法可以编写它,以便在用户排序时rails不会重新查询结果
我目前正在尝试了解RoR。我将两个字符串传递到我的Controller中。一个是随机的十六进制字符串,另一个是电子邮件。该项目用于对数据库进行简单的电子邮件验证。我遇到的问题是当我输入如下内容来测试我的页面时:http://signup.testsite.local/confirm/da2fdbb49cf32c6848b0aba0f80fb78c/bob.villa@gmailcom我在:email的参数散列中得到的全部是'bob'。我在gmail和com之间留下了.,因为那样会导致匹配根本不起作用。我的路由匹配如下:match"confirm/:code/:email"=>"conf
我正在寻找一种方便实用的方法来将编码值添加到Ruby中的URL查询字符串。目前,我有:require'open-uri'u=URI::HTTP.new("http",nil,"mydomain.example",nil,nil,"/tv",nil,"show="+URI::encode("Rosie&Jim"),nil)pu.to_s#=>"http://mydomain.example/tv?show=Rosie%20&%20Jim"这不是我要找的,因为我需要得到“http://mydomain.example/tv?show=Rosie%20%26%20Jim”,这样show=值就
我正在尝试将种子数据从CSV文件加载到我的Rails应用程序中。我最初安装了fastercsvgem,却发现从ruby1.9开始,fastercsv已被弃用,取而代之的是CSV库。所以在收到一个非常有用的错误告诉我切换后,我切换到CSV。然而,现在我遇到了最奇怪的现象,当我加载数据时一切看起来都很正常,但我似乎无法查询字符串字段。字符串字段由看似正确的字符串填充,但我无法访问它们。我可以查询任何数字字段,结果将返回,但不会返回字符串字段。我尝试使用引号的定界符,但无济于事。我什至从我的csv文件中删除了所有引号,但我仍然无法查询字符串字段。下面是我的代码,以及一些来自Rails控制