Tsql 当子查询没有引入EXISTS时,如何在select列表中指定两个表达式
我有一个使用子查询的查询,返回预期结果时遇到问题。我收到的错误是…“当子查询没有引入EXISTS时,只能在选择列表中指定一个表达式。”我如何重写该表达式才能工作Tsql 当子查询没有引入EXISTS时,如何在select列表中指定两个表达式,tsql,sql-server-2012-express,Tsql,Sql Server 2012 Express,我有一个使用子查询的查询,返回预期结果时遇到问题。我收到的错误是…“当子查询没有引入EXISTS时,只能在选择列表中指定一个表达式。”我如何重写该表达式才能工作 SELECT a.Part, b.Location, b.LeadTime FROM dbo.Parts a LEFT OUTER JOIN dbo.Vendor b ON b.Part = a.Part WHERE b.Location IN ('A','B','C') AND
SELECT
a.Part,
b.Location,
b.LeadTime
FROM
dbo.Parts a
LEFT OUTER JOIN dbo.Vendor b ON b.Part = a.Part
WHERE
b.Location IN ('A','B','C')
AND
Date IN (SELECT Location, MAX(Date) FROM dbo.Vendor GROUP BY Location)
GROUP BY
a.Part,
b.Location,
b.LeadTime
ORDER BY
a.Part
在子查询中,需要将位置和零件与外部查询关联起来。 例如:
Date = (SELECT MAX(Date)
FROM dbo.Vender v
WHERE v.Location = b.Location
AND v.Part = b.Part
)
因此,这将为子查询中的每个位置和部分返回一个日期,您需要将位置和部分与外部查询关联起来。 例如:
Date = (SELECT MAX(Date)
FROM dbo.Vender v
WHERE v.Location = b.Location
AND v.Part = b.Part
)
因此,这将为每个位置和零件返回一个日期如果我正确理解您的意思,您希望位置A、B和C的行具有最大日期。现在,假设SQL Server 2005+,您可以执行以下操作:
;WITH CTE AS
(
SELECT
a.Part,
b.Location,
b.LeadTime,
RN = ROW_NUMBER() OVER(PARTITION BY a.Part ORDER BY [Date] DESC)
FROM
dbo.Parts a
LEFT OUTER JOIN dbo.Vendor b ON b.Part = a.Part
WHERE
b.Location IN ('A','B','C')
)
SELECT Part,
Location,
LeadTime
FROM CTE
WHERE RN = 1
ORDER BY Part
如果我正确理解了您的意思,那么您希望位置A、B和C的行具有最大日期。现在,假设SQL Server 2005+,您可以执行以下操作:
;WITH CTE AS
(
SELECT
a.Part,
b.Location,
b.LeadTime,
RN = ROW_NUMBER() OVER(PARTITION BY a.Part ORDER BY [Date] DESC)
FROM
dbo.Parts a
LEFT OUTER JOIN dbo.Vendor b ON b.Part = a.Part
WHERE
b.Location IN ('A','B','C')
)
SELECT Part,
Location,
LeadTime
FROM CTE
WHERE RN = 1
ORDER BY Part
我想这可能就是你想要的。您没有说明SQL Server的哪个版本--这在SQL 2005及更高版本中有效:
SELECT
p.Part,
p.Location, -- from *p*, otherwise if no match we'll get a NULL
v.LeadTime
FROM
dbo.Parts p
OUTER APPLY (
SELECT TOP (1) * -- * here is okay because we specify columns outside
FROM dbo.Vendor v
WHERE p.Location = v.Location -- the correlation part
ORDER BY v.Date DESC
) v
WHERE
p.Location IN ('A','B','C')
ORDER BY
p.Part
;
现在,可以通过添加“correlation”部分将查询更改为相关子查询来修复查询,如中所示(还可以删除GROUP by
子句)。但是,该方法仍然需要额外的、不必要的连接,这会影响性能,而且一次只能拉一列。此方法允许您从另一个表中提取所有列,并且没有额外的联接
注意:这在逻辑上给出了与相同的结果,但出于以下几个原因,我更喜欢它:
当相关列(位置
,此处)上有索引时,搜索可以满足这一要求,但行号
解决方案必须扫描(我相信)
我更喜欢这种更直接、简洁地表达查询意图的方式。在Row\u Number
方法中,必须进入外部条件,查看我们仅获取rn=1
值,然后返回到CTE中,查看这是什么
使用交叉应用
或外部应用
,每个外部行选择的单个内部行中未涉及的所有其他表都位于(对我而言)它们所属的位置之外。我们不是在一起解决问题。使用Row\u Number
感觉有点像在查询上抛出一个DISTINCT
来修复重复,而不是处理底层问题。我想这基本上是同一个问题,因为前面的观点用了不同的措辞
当您有两个表要从中提取最新的值时,行编号()
解决方案就会完全崩溃。使用这种语法,您只需简单地添加另一个APPLY
子句,您所做的事情就一目了然了。对于多表场景,有一种方法可以通过将其他表移到外部来使用Row\u Number
,但我仍然不喜欢这种语法
使用此语法,您可以根据所选行是否存在(在未找到匹配行的情况下)执行其他联接。在Row\u Number
解决方案中,您只能合理地在外部查询中执行notnull
检查——因此,您必须将查询拆分为多个独立的部分(您不希望加入将要丢弃的值!)
另外,我强烈建议你使用别名来暗示他们所代表的表格。请不要使用a
和b
。我将p
用于零件
和v
用于供应商
——这有助于您和其他人在将来更快地理解查询。我想这可能是您正在寻找的东西。您没有说明SQL Server的哪个版本--这在SQL 2005及更高版本中有效:
SELECT
p.Part,
p.Location, -- from *p*, otherwise if no match we'll get a NULL
v.LeadTime
FROM
dbo.Parts p
OUTER APPLY (
SELECT TOP (1) * -- * here is okay because we specify columns outside
FROM dbo.Vendor v
WHERE p.Location = v.Location -- the correlation part
ORDER BY v.Date DESC
) v
WHERE
p.Location IN ('A','B','C')
ORDER BY
p.Part
;
现在,可以通过添加“correlation”部分将查询更改为相关子查询来修复查询,如中所示(还可以删除GROUP by
子句)。但是,该方法仍然需要额外的、不必要的连接,这会影响性能,而且一次只能拉一列。此方法允许您从另一个表中提取所有列,并且没有额外的联接
注意:这在逻辑上给出了与相同的结果,但出于以下几个原因,我更喜欢它:
当相关列(位置
,此处)上有索引时,搜索可以满足这一要求,但行号
解决方案必须扫描(我相信)
我更喜欢这种更直接、简洁地表达查询意图的方式。在Row\u Number
方法中,必须进入外部条件,查看我们仅获取rn=1
值,然后返回到CTE中,查看这是什么
使用交叉应用
或外部应用
,每个外部行选择的单个内部行中未涉及的所有其他表都位于(对我而言)它们所属的位置之外。我们不是在一起解决问题。使用Row\u Number
感觉有点像在查询上抛出一个DISTINCT
来修复重复,而不是处理底层问题。我想这基本上是同一个问题,因为前面的观点用了不同的措辞
当您有两个表要从中提取最新的值时,行编号()
解决方案就会完全崩溃。使用这种语法,您只需简单地添加另一个APPLY
子句,您所做的事情就一目了然了。对于多表场景,有一种方法可以通过将其他表移到外部来使用Row\u Number
,但我仍然不喜欢这种语法
使用此语法,您可以根据所选行是否存在(在未找到匹配行的情况下)执行其他联接。在行中\u编号<