避免重复引用多个连接表的子查询

sha*_*non 4 sql t-sql sql-server

我有一个子查询(LastActivityOn),我想在三个地方使用,我的投影(SELECTed输出),ORDER BY和WHERE子句.

SELECT TOP 175
  (SELECT MAX(ActivityDate) FROM (VALUES
    (UserRegistration.CreatedOn),
    (UserRegistration.ActivatedOn),
    (UserRegistration.LastLoginOn),
    (UserRegistration.UpdatedOn),
    (UserProfile.LastPostedOn)) AS AllDates(ActivityDate)) LastActivityOn,
  UserRegistration.FirstName,
  UserRegistration.LastName,
  [15 more columns of various calculated distances, coalesces, etc...]
FROM
  UserRegistration
  INNER JOIN UserProfile ON UserRegistration.Id = UserProfile.RegistrationId
  INNER JOIN (
    SELECT PostalCode, GeoCenter, PrimaryCity, StateOrProvince
    FROM PostalCodes 
    WHERE @OriginPostalCode IS NULL OR PostalCodes.GeoCenter.STDistance(@OriginPoint) < @WithinMeters
  ) AS ProximalPostalCodes ON ProximalPostalCodes.PostalCode = UserRegistration.PostalCode
  [7 more joins including full-text queries]
WHERE
  LastActivityOn > @OldestUserToSearch AND
  [20 more lines of filtering logic]
ORDER BY
  LOG(DATEDIFF(WEEK, LastActivityOn, @Today))/LOG(2),
  FullTextRelevance
Run Code Online (Sandbox Code Playgroud)

注意LastConctivityOn的三次出现.另请注意,LastActivityOn子查询引用了两个表.我想因为它依赖于父查询中的join子句,它本质上是一个相关的子查询?

当我只通过User-Defined-Function获取最多两个日期时,我能够在WHERE和ORDER BY中使用结果值.我现在不可以.

看起来我有几个选项...我可以将整个事情包装在另一个查询中,只使用添加的活动重复投影.似乎我可以以相同的方式使用"WITH"(CTE).

但是因为我不清楚我什么时候能够按照自己想要的方式使用子查询的规则,所以我很容易丢失一些东西.有任何想法吗?

或者SQL SERVER可能足够智能,只能为每个输出行执行一次计算,我不应该担心它吗?

编辑:当前正在运行SQL Server 2008 Standard,但升级将在某些时候按顺序进行.此外,RE:日志功能 - 我正在努力将相关性与加权总和相结合,因此这是一项正在进行中的工作.我会用INT修剪它以用作一种排名,或者将其添加到线性调整的相关性.

更正:我能够在我的ORDER BY中使用子查询别名,但不能在任何其他计算或where子句中使用.感谢ypercube指出这一点.

dem*_*mas 6

我不会尝试修改您的查询,但可能是常见的表表达式是您所需要的.