我认为这样的东西可能是你正在寻找的东西。您没有说 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
;
现在,您的查询可以通过添加“相关”部分来修复您的查询,以将您的查询更改为 a correlated subquery
,如Kory 的答案所示(您还可以删除该GROUP BY
子句)。但是,该方法仍然需要额外的不必要的连接,这会损害性能,而且一次只能拉一列。此方法允许您从另一个表中提取所有列,并且没有额外的连接。
注意:这在逻辑上给出了与Lamak 的答案相同的结果,但是出于以下几个原因,我更喜欢它:
- 当相关列(
Location
此处的 , )上有索引时,可以通过搜索来满足,但Row_Number
解决方案必须扫描(我相信)。
- 我更喜欢这种更直接、更简洁地表达查询意图的方式。在该
Row_Number
方法中,必须了解外部条件以查看我们只是在获取rn = 1
值,然后返回 CTE 以查看它是什么。
- 使用
CROSS APPLY
or OUTER APPLY
,未参与单内行每外行选择的所有其他表都在(对我而言)它们所属的位置之外。我们不会一起解决问题。使用Row_Number
感觉有点像DISTINCT
在查询上抛出一个来修复重复而不是处理潜在问题。我想这与前一点以不同的方式表达的问题基本相同。
- 当您有两张表希望从中提取最新值时,
Row_Number()
解决方案就彻底崩溃了。使用这种语法,您只需轻松添加另一个APPLY
子句,您在做什么就一目了然。有一种方法可以Row_Number
通过将其他表移到外部来用于多表场景,但我仍然不喜欢这种语法。
- 使用此语法,您可以根据所选行是否存在(在未找到匹配行的情况下)执行附加连接。在
Row_Number
解决方案中,您只能合理地NOT NULL
检查外部查询——因此您被迫将查询拆分为多个独立的部分(您不想加入将要丢弃的值!)。
PS 我强烈建议您使用暗示它们所代表的表的别名。请不要使用a
and b
。我使用p
了 forParts
和v
for Vendor
--this 可以帮助您和其他人在未来更快地理解查询。