2010-04-21 35 views
1

我想加入一個包含WITH子句的子查詢/派生表(WITH子句必須在ROW_NUMBER() = 1上過濾)。在Teradata類似的情況下可以正常工作,但Teradata使用QUALIFY ROW_NUMBER() = 1而不是WITH子句。SQL Server:加入包含WITH子句的派生表?

這是我在這次嘗試加入:

-- want to join row with max StartDate on JobModelID 
INNER JOIN (
    WITH AllRuns AS (
     SELECT *, 
      ROW_NUMBER() OVER (PARTITION BY JobModelID ORDER BY StartDate DESC) AS RowNumber 
     FROM Runs 
    ) 
    SELECT * FROM AllRuns WHERE RowNumber = 1 
) Runs 
ON JobModels.JobModelID = Runs.JobModelID 

我在做什麼錯?

回答

0

添加一個連接條件可能是低效率的,但通常工作正常,我。

INNER JOIN (
    SELECT *, 
      ROW_NUMBER() OVER 
      (PARTITION BY JobModelID 
      ORDER BY StartDate DESC) AS RowNumber 
     FROM Runs 
    ) Runs 
ON JobModels.JobModelID = Runs.JobModelID 
AND Runs.RowNumber = 1 
+0

任何想法這將是多少效率? – jnylen 2010-04-21 17:13:56

+1

@jnylen,你有沒有試圖分析這個查詢?執行計劃,Profiler,客戶統計? – 2010-04-21 17:30:41

+0

@jnylen:我同意你的觀點。我的經驗法則:如果查詢在合理的時間內恢復,那就沒問題。如果不是,我開始尋找熱點並嘗試重構。我從來沒有像上面顯示的那樣重構代碼。 – bernie 2010-04-21 17:48:20

1

您可以使用多個WITH子句。像

;WITH AllRuns AS ( 
     SELECT *, 
       ROW_NUMBER() OVER (PARTITION BY JobModelID ORDER BY StartDate DESC) AS RowNumber 
     FROM Runs 
), 
Runs AS(
     SELECT * 
     FROM AllRuns 
     WHERE RowNumber = 1 
) 

SELECT * 
FROM ... INNER JOIN ( 
     Runs ON JobModels.JobModelID = Runs.JobModelID 

東西更詳細的用法/結構/規則見WITH common_table_expression (Transact-SQL)

+0

醜陋,但它似乎工作。這裏的根本問題是什麼 - 在派生表中缺少對WITH子句的支持?另外,我可以通過加入'(SELECT * FROM AllRuns WHERE RowNumber = 1)'來消除第二個WITH子句。 – jnylen 2010-04-21 16:44:57

+0

我會不同意這樣一個事實,即在with子句中的多個記述是UGLY。它與多層次子選擇略有不同,**在大多數情況下,它使得它非常難以閱讀。** – 2010-04-21 16:51:11

+0

我的意思是,在執行子查詢任務時使用SQL(過濾「運行」表以獲取「JobModelID」每行一行)現在在查詢的開始和子查詢之間分開。 – jnylen 2010-04-21 17:03:04