如何按日期从另一个表中选择最新项目

时间:2015-07-01 10:59:41

标签: sql sql-server-2008

我有两个表项目和计划,我需要通过创建日期从上一个计划中获取最近的项目:

Projects:
ProjectId, PlanId, StartDate, EndDate 
(guid)     (guid)  (datetime) (datetime)
-------------------------------------
00001,     00001,  1/1/2015   31/1/2015   
00001,     00002,  3/2/2015   15/2/2015   
00002,     00001,  1/2/2015   20/2/2015   
00002,     00002,  1/2/2015   21/2/2015   
00003,     00001,  1/3/2015   10/3/2015   

Plans:
PlanId, CreateDate
(guid)  (datetime)
--------------------
00001,   1/1/2015
00002,   5/2/2015

我编写了从最后一个计划中获取单个项目的查询,但我不能通过单个查询编写查询来获取许多项目。

这是我的查询:

SELECT TOP 1 pr.ProjectId,
        pl.CreateDate,
        pr.StartDate,
        pr.EndDate
FROM   Projects pr
        INNER JOIN Plans pl
            ON  pr.PlanId = pl.PlanId
WHERE ProjectId = '000002'
ORDER BY pl.CreateDate DESC

期望的结果是(最后计划中的所有项目):

ProjectId, PlanId, StartDate, EndDate
--------------------------------------
00001,     00002,  3/2/2015,  15/2/2015
00002,     00002,  1/2/2015,  21/2/2015
00003,     00001,  1/3/2015,  10/3/2015

更新 Gordon Linoff给出了很好的答案,但是我的问题没有解决,因为他的两个问题都没有采取'00003'项目(最后的计划是'00001')。

我用'OVER Clause'写了我的查询(StanislovasKalašnikovas注意到它)。

所以我发布了完整的答案,为未来的googlers解决了我的问题:

SELECT * FROM
    (SELECT 
        result.ProjectId, 
        result.CreateDate, 
        result.StartDate, 
        result.EndDate, 
        ROW_NUMBER() OVER (PARTITION BY ProjectId ORDER BY CreateDate DESC) AS RowNumber
    FROM ( 
            SELECT  pr.ProjectId AS ProjectId,
                    pl.CreateDate AS CreateDate,
                    pr.StartDate AS StartDate,
                    pr.EndDate AS EndDate
            FROM   Projects pr
            INNER JOIN Plans pl ON  pr.PlanId = pl.PlanId
            --WHERE ProjectId IN ('000001', '000003') --Filter
         ) AS result
) AS result
WHERE result.RowNumber = 1

3 个答案:

答案 0 :(得分:2)

您可以使用子查询来获取最新计划。然后加入项目:

SELECT pr.ProjectId, pl.CreateDate, pr.StartDate, pr.EndDate
FROM (SELECT TOP 1 pl.*
      FROM plans pl
      ORDER BY pl.CreateDate DESC
     ) pl JOIN
     Projects pr
     ON pr.PlanId = pl.PlanId;
WHERE ProjectId = '000002'

另一种方法是使用TOP WITH TIES

SELECT TOP 1 WITH TIES pr.ProjectId, pl.CreateDate, pr.StartDate, pr.EndDate
FROM plans pl
     Projects pr
     ON pr.PlanId = pl.PlanId;
WHERE ProjectId = '000002'
ORDER BY pl.CreateDate DESC

答案 1 :(得分:1)

这是带{1}的ROW_NUMBER示例,您可以轻松使用它。

CREATE TABLE #Test
(
Id NVARCHAR(100),
Data DATE
)

INSERT INTO #Test VALUES ('1', '2015-01-04'), ('1', '2015-01-07'), ('2', '2015-01-05'), ('2', '2015-01-08')

SELECT Id, Data
FROM (
    SELECT Id, Data, ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Data DESC) rn
    FROM #Test
    )x
WHERE rn > 1


DROP TABLE #Test

答案 2 :(得分:0)

您可以使用datediff(),例如,如果您想使用过去10天的条目,请使用:

SELECT  pr.ProjectId,
        pl.CreateDate,
        pr.StartDate,
        pr.EndDate
FROM   Projects pr
        INNER JOIN Plans pl
            ON  pr.PlanId = pl.PlanId
WHERE datediff(day,pl.CreateDate,getdate())<10