1

這是一個更大的聲明的一部分,但我想知道CTE或其他方法是否有助於提高效率或清潔度。我可以把它寫成一個表值函數,並將其包含在我的from子句中,但如果有另一個解決方案,我想避免額外的對象。如何減少許多類似的相關子查詢?

SELECT TOP 1 ...SELECT TOP 1 ...這裏的子查詢只是在我有一個早於生效日期的基準表的速率時被捕獲,但我不喜歡爲我需要訪問的每一列重複它們。有沒有更好的方法來完成這個,或者這是一個正常的前瞻性陳述?

SELECT j.EmployeeId 
     ,j.CompanyId 
     ,j.JobCode 
     ,COALESCE(j.CustomWageRate, r.WageRate, (SELECT TOP 1 WageRate 
               FROM ContractLabor.CompanyJobRates 
               WHERE CompanyId = j.CompanyId 
                 AND JobCode = j.JobCode 
                 AND EffectiveDate < j.EffectiveDate 
               ORDER BY EffectiveDate DESC), 0) AS EffectiveRate 
     ,COALESCE(r.CustomBurdenRateReg, (SELECT TOP 1 CustomBurdenRateReg 
             FROM ContractLabor.CompanyJobRates 
             WHERE CompanyId = j.CompanyId 
               AND JobCode = j.JobCode 
               AND EffectiveDate < j.EffectiveDate 
             ORDER BY EffectiveDate DESC)) AS CustomBurdenRateReg 
     ,COALESCE(r.CustomBurdenRateOvt, (SELECT TOP 1 CustomBurdenRateOvt 
             FROM ContractLabor.CompanyJobRates 
             WHERE CompanyId = j.CompanyId 
               AND JobCode = j.JobCode 
               AND EffectiveDate < j.EffectiveDate 
             ORDER BY EffectiveDate DESC)) AS CustomBurdenRateOvt 
     ,COALESCE(r.CustomBurdenRateDbl, (SELECT TOP 1 CustomBurdenRateDbl 
             FROM ContractLabor.CompanyJobRates 
             WHERE CompanyId = j.CompanyId 
               AND JobCode = j.JobCode 
               AND EffectiveDate < j.EffectiveDate 
             ORDER BY EffectiveDate DESC)) AS CustomBurdenRateDbl 
     ,j.EffectiveDate 
FROM ContractLabor.EmployeeJobDetails j 
     LEFT JOIN ContractLabor.CompanyJobRates r 
     ON j.CompanyId = r.CompanyId 
      AND j.JobCode = r.JobCode 
      AND j.EffectiveDate = r.EffectiveDate 

回答

3
SELECT j.EmployeeId 
     ,j.CompanyId 
     ,j.JobCode 
     ,COALESCE(j.CustomWageRate, r.WageRate, ca.WageRate, 0) AS EffectiveRate 
     ,COALESCE(r.CustomBurdenRateReg, ca.CustomBurdenRateReg) AS CustomBurdenRateReg 
     ,COALESCE(r.CustomBurdenRateOvt, ca.CustomBurdenRateOvt) AS CustomBurdenRateOvt 
     ,COALESCE(r.CustomBurdenRateDbl, ca.CustomBurdenRateDbl) AS CustomBurdenRateDbl 
     ,j.EffectiveDate 
FROM ContractLabor.EmployeeJobDetails j 
     LEFT JOIN ContractLabor.CompanyJobRates r 
     ON j.CompanyId = r.CompanyId 
      AND j.JobCode = r.JobCode 
      AND j.EffectiveDate = r.EffectiveDate 

     OUTER APPLY --or CROSS APPLY 
     (
      SELECT TOP 1 WageRate 
        ,CustomBurdenRateReg 
        ,CustomBurdenRateOvt 
        ,CustomBurdenRateDbl 
      FROM ContractLabor.CompanyJobRates 
      WHERE CompanyId = j.CompanyId 
        AND JobCode = j.JobCode 
        AND EffectiveDate < j.EffectiveDate 
      ORDER BY EffectiveDate DESC  
     ) ca 
+0

啊,好多了。 「外部應用」是我不知道尋找的缺失部分。謝謝。 – JustinStolle

+0

不客氣。您可以使用「SET STATISTICS IO ON」來查看這兩個查詢完成了多少個邏輯和物理讀取。越少越好。 [使用APPLY](http://msdn.microsoft.com/en-us/library/ms175156%28v=SQL.90%29.aspx)。 –

2

你可以使用跨應用/頂1,選擇一次性全部相關列上加入一個派生表表達式中的外部查詢。然後

您的查詢可能看起來像:

SELECT ..., ISNULL(x, defaultValues.x) 
FROM ... 
    CROSS APPLY (SELECT TOP(1) x, y, z FROM ... WHERE ... ORDER BY ...) defaultValues 

這將是更有效,因爲有較少的查詢連接(每一個你原來的相關子查詢的變成一個外部聯接)。

您也可以使用OUTER APPLY作爲外部聯接功能。

+0

謝謝。是的,在這種情況下,「外部應用」適用於我。 – JustinStolle