2013-02-20 41 views
2

我的設置是我有兩個表Study和Activity_History。活動在研究中進行,因此存在一對多的關係。在SQL子查詢中使用多列

我希望能夠在Activity_History表上運行一個SQL查詢,這將使我獲得活動和以前運行的活動。我目前有這樣的:

SELECT 
     * 
FROM Activity_History AS A1 
LEFT JOIN Activity_History AS A2 
ON A2.Parent_Study_ID = 
(
    SELECT TOP 1 Parent_Study_ID 
    FROM Activity_History AS A3 
    WHERE A3.Parent_Study_ID = A1.Parent_Study_ID 
      AND A3.Activity_Date < A1.Activity_Date 
    ORDER BY Activity_Date DESC 
) 

這是行不通的。發生什麼事是它拉動查詢的Activity_Date方沒有任何作用,它只是按照每行的降序日期順序返回第一個匹配的Activity_Date。我認爲這是因爲在我的子查詢中我在使用Activity_Date的地方,但這不在子查詢select中。

感謝您的幫助!

+0

你可以請加表模式,列名 – dekdev 2013-02-20 18:17:25

+0

什麼是「*這是行不通的*」是什麼意思? – RBarryYoung 2013-02-20 18:20:41

+1

你不應該需要在你的'SELECT'中的WHERE中包含所有的列......你得到的錯誤是什麼? – 2013-02-20 18:21:06

回答

3

我假設你使用的是SQL Server?如果是這樣,那麼這應該使用ROW_NUMBER():

WITH CTE AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY Parent_Study_Id ORDER BY Activity_Date) RN 
    FROM Activity_History 
    ) 
SELECT * 
FROM CTE T1 
    LEFT JOIN CTE T2 ON T1.RN = T2.RN+1 AND T1.Parent_Study_Id = T2.Parent_Study_Id 

這裏是SQL Fiddle

+1

正確的表達式是'row_number()over(由parent_study_id按activity_date排序的分區)'。 – 2013-02-20 18:19:49

+0

@GordonLinoff - 謝謝,在原始查詢中沒有看到 - 在Fiddle上工作並且速度太快了!謝謝! – sgeddes 2013-02-20 18:21:35

+0

太棒了,效果很好。 Row_Number()是一個非常酷的功能。 – 2013-02-20 21:39:18

0

在SQLServer2005的,而不是+ LEFT JOIN你需要使用OUTER APPLY

SELECT * 
FROM Activity_History AS A1 OUTER APPLY ( 
             SELECT TOP 1 Parent_Study_ID 
             FROM Activity_History AS A2 
             WHERE A2.Parent_Study_ID = A1.Parent_Study_ID 
              AND A2.Activity_Date < A1.Activity_Date 
             ORDER BY A2.Activity_Date DESC 
             ) o