2012-11-01 80 views
2

我有一個相當複雜的連接查詢,我想從中選擇圍繞具有某個ID的結果的幾行。用連接返回具有特定值的行

查詢目前看起來是這樣的:

WITH results AS 
    (
    SELECT t1.id, t1.position, t1.points, t2.name 
     ROW_NUMBER() OVER(ORDER BY t1.position ASC, t1.points DESC) AS rn 
     FROM Table1 t1 
     JOIN Table2 t2 ON t1.id = t2.Table1id 
     /* Several more joins here, some of which limit the result set */ 
) 
SELECT * FROM results 
WHERE rn < (SELECT rn+3 FROM results WHERE id = @someid) 
AND rn > (SELECT rn-3 FROM results WHERE id = @someid) 

有沒有更好的辦法來解決這個問題?最重要的是,我擔心這些多次呼叫可能會導致巨大的CTE表現。

該查詢在SQL 2008服務器上運行。

+1

在SQL 2012中,您具有'LAG'和'LEAD'功能。但如果你使用的是SQL 2008或以前的版本,那將無濟於事 – podiluska

+0

這樣做可能會做到,但我在SQL 2008上,可悲的是...... – Jan

回答

1

也許從CTE拉出連接。
這樣查詢優化器有機會在處理連接之前過濾出行。

WITH results AS 
    (
    SELECT t1.id, t1.position, t1.points 
     , ROW_NUMBER() OVER(ORDER BY t1.position ASC, t1.points DESC) AS rn 
     FROM Table1 t1  
) 
SELECT results.id, results.position, results.points, t2.name 
FROM results 
JOIN Table2 t2 ON t2.id = results.Table1id 
     /* Several more joins here */ 
WHERE rn < (SELECT rn+3 FROM results WHERE id = @someid) 
    AND rn > (SELECT rn-3 FROM results WHERE id = @someid) 
+0

這是一個很好的建議,只是在這種情況下,連接也被使用限制顯示的數據。我仍然需要一個(可能是巨大的)CTE內部的'WHERE id IN(/ *加入here * /)'來獲得行號,以及在CTE之外的連接以獲取其中的數據。雖然... – Jan

+0

從您的示例中,我假定連接不會限制行。直到你測試真實的數據時才猜測。它取決於多少過濾器與連接,索引以及查詢優化器做出的決定。 – Paparazzi