仅从更新历史记录中检索重新激活的项目

时间:2011-11-17 20:17:22

标签: sql

所以我有一个跟踪项目状态更新的表。现在,每次项目更改状态时,都会将其记录插入到新行中。该表的简化形式如下所示:

+-----------+------------+--------+
| ProjectID | UpdateDate | Status |
+-----------+------------+--------+
|           |            |        |
|           |            |        |
|           |            |        |
+-----------+------------+--------+

Status列的可能值为:

     
  • 重新激活
  •  
  •  
  •  
  • 有效

现在这里至少对我来说很棘手。我希望能够只选择当前重新激活的项目。这在逻辑上意味着一个项目具有已重新激活的现有行作为其状态,但没有将该ID的最新记录作为已关闭状态。感谢您对此的任何帮助,我很难为此查看SQL查询。

BONUS (对我来说)

如果您可以将查询编写为一个非常棒的创建存储过程。

更新

强调重新激活的要求。

更新更新

一些测试数据

ProjectID | UpdateDate   |  Status  
-----------------------------------
3566      | 2011-11-09   |  Pending 
1282      | 2011-11-17   |  Reactivated 
3351      | 2011-11-17   |  Closed  
2252      | 2011-11-17   |  Reactivated 
2252      | 2011-11-17   |  Active  

现在有了这个查询,它应该显示id的1282和2252,因为它们都已连续重新激活,并且没有作为最后更新状态关闭。

4 个答案:

答案 0 :(得分:1)

这是“最近重新激活”

select
    *
  from
    Project P -- I'm guessing at this table name
    join
    (select MAX(UpdateDate) lastUpdate, ProjectId from Project group by ProjectId) L on L.ProjectId = P.ProjectId AND L.lastUpdate = P.UpdateDate        
  where 
    Status = 'Reactivated'

这是“最近没有关闭,但在某些时候已被重新激活”,这就是你要求的

select distinct  -- there may be more than one "reactivated" per project
    R.ProjectId
  from
    Project R join        
    (select
        P.ProjectId
      from
        Project P join
        (select
            MAX(InsertDate) InsertDate,
            ProjectId
          from
            Project 
          group by
            ProjectId) MostRecent M on P.InsertDate = M.InsertDate and P.ProjectId = M.ProjectId
      where
        Status <> 'Closed') O on O.ProjectId = R.ProjectId
  where
    Status = 'Reactivated'

答案 1 :(得分:0)

选择所有重新激活的项目并检查它是否处于关闭状态。

它没有优化,但我认为它有效。

SELECT p1.*
FROM project as p1
WHERE Status = "Reactivated"
AND ProjectID NOT IN (SELECT ProjectID FROM project AS p2 WHERE Status = "Closed" AND p2.Updatedate > p1.UpdateDate)

测试

|-ProjectID-|-UpdateDate-|-   Status    -|
|-    1    -|-2011-11-15-|- Closed      -|
|-    1    -|-2011-11-16-|- Reactivated -|
|-    1    -|-2011-11-17-|- Opened      -|
|-    2    -|-2011-11-15-|- Reactivated -|
|-    2    -|-2011-11-16-|- Closed      -|
|-    2    -|-2011-11-17-|- Reactivated -|
|-    3    -|-2011-11-15-|- Closed      -|
|-    3    -|-2011-11-16-|- Reactivated -|
|-    3    -|-2011-11-17-|- Closed      -|

结果

|-ProjectID-|-UpdateDate-|-   Status    -|
|-    1    -|-2011-11-16-|- Reactivated -|
|-    2    -|-2011-11-17-|- Reactivated -|

答案 2 :(得分:0)

这是我的解决方案(有sp奖励))

CREATE PROC sp_GetReactivatedProjects
AS
    SELECT RA.ProjectID 
    FROM 
        (SELECT ProjectID, max(UpdateDate) as RaDate
         FROM Project 
         WHERE Status = 'Reactivated'
         GROUP BY ProjectID) RA
    LEFT JOIN 
        (SELECT ProjectID, max(UpdateDate) as ClDate
         FROM Project 
         WHERE Status = 'Closed'
         GROUP BY ProjectID) Cl
    ON RA.ProjectId = Cl.ProjectID
    WHERE raDate > ClDate or ClDate is null

希望它会有所帮助

答案 3 :(得分:0)

救援不存在!

-- generate some data
DROP TABLE tmp.projects;
CREATE TABLE tmp.projects
    ( projectid INTEGER NOT NULL
    , updatedate DATE NOT NULL
    , status varchar
    , PRIMARY KEY (projectid,updatedate)
    );
INSERT INTO tmp.projects VALUES
  (    1    , '2011-11-15' , 'Closed' )
, (    1    , '2011-11-16' , 'Reactivated' )
, (    1    , '2011-11-17' , 'Opened' )
, (    2    , '2011-11-15' , 'Reactivated' )
, (    2    , '2011-11-16' , 'Closed' )
, (    2    , '2011-11-17' , 'Reactivated' )
, (    3    , '2011-11-15' , 'Closed' )
, (    3    , '2011-11-16' , 'Reactivated' )
, (    3    , '2011-11-17' , 'Closed' )
    ;

SET search_path='tmp';

SELECT * FROM projects p1;

SELECT * FROM projects p1
WHERE status = 'Reactivated'
AND NOT EXISTS ( SELECT *
    FROM projects nx
    WHERE nx.projectid = p1.projectid
    AND nx.updatedate > p1.updatedate
    AND nx.status IN ( 'Closed' , 'Reactivated' )
    AND NOT EXISTS (SELECT *
        FROM projects zlast
        WHERE zlast.projectid = nx.projectid
        AND zlast.updatedate > nx.updatedate
        )   
    );

结果:

CREATE TABLE
INSERT 0 9
SET
 projectid | updatedate |   status    
-----------+------------+-------------
         1 | 2011-11-15 | Closed
         1 | 2011-11-16 | Reactivated
         1 | 2011-11-17 | Opened
         2 | 2011-11-15 | Reactivated
         2 | 2011-11-16 | Closed
         2 | 2011-11-17 | Reactivated
         3 | 2011-11-15 | Closed
         3 | 2011-11-16 | Reactivated
         3 | 2011-11-17 | Closed
(9 rows)

 projectid | updatedate |   status    
-----------+------------+-------------
         1 | 2011-11-16 | Reactivated
         2 | 2011-11-17 | Reactivated
(2 rows)

可能存在递归CTE; - )