射影 (SELECT された出力)、ORDER BY、および WHERE 句の 3 つの場所で使用したいサブクエリ ( LastActivityOn ) があります。
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
LastActivityOn が 3 回発生していることに注意してください。また、LastActivityOn サブクエリは 2 つのテーブルを参照することに注意してください。親クエリの結合句に依存しているため、本質的に相関サブクエリですか?
ユーザー定義関数を介して最大 2 つの日付のみを取得していたとき、結果の値を WHERE および ORDER BY で使用できました。現在、私はできません。
いくつかのオプションがあるようです...すべてを別のクエリでラップし、追加されたアクティビティだけで射影を繰り返すことができます。同じように "WITH" (CTE) を使用できるようです。
しかし、サブクエリを思いどおりに使用できる場合と使用できない場合のルールを明確に理解していないため、簡単に何かを見落としている可能性があります。何か案は?
それとも、SQL SERVER は出力行ごとに 1 回だけ計算を実行するほどスマートであり、心配する必要はないのでしょうか?
編集: 現在 SQL Server 2008 Standard を実行していますが、アップグレードはある時点で順番に行われます。また、RE: ログ関数 - 加重合計としての関連性と組み合わせる作業を行っているため、これは進行中の作業です。ランキングの一種として使用するために INT でトリミングするか、線形調整で関連性を追加します。
訂正: ORDER BY でサブクエリ エイリアスを使用できましたが、追加の計算や where 句では使用できませんでした。それを指摘してくれたypercubeに感謝します。