如何确定每个组中所有 joining/leaving 记录的净效应?

How can I determine the nett effect of all joining/leaving records in each group?

稍微简化一下,我有一个 table 显示组织成员的状态记录。他们通过成为 'Active' 加入,并可以通过成为 'Resigned'、'Lapsed' 或 'Deceased' 离开。有一个或多个连续离职记录只算离职一次,在最早离职记录的日期。如果发生这种情况,加入记录也是如此。

使用 member_id 和更改数据将状态的每个更改记录为一条记录。一个会员可能有多个状态变更记录。

我需要能够按每个成员分组,并确定某个成员在给定年份(比如 2015 年)的所有记录的总体结果是否会导致组织的净收益或损失,从而使它们成为加入者或离开者(如果效果取消,则什么都没有)。 我想要的结果是 (a) 有多少加入者以及他们是谁以及 (b) 有多少离开者以及他们是谁。

任何人都可以帮助我使用正确的编码技术来按顺序、时间顺序处理一个成员的所有记录以确定该成员的净值结果吗?

下面是一个示例架构和数据 - 另请参阅 SQLfiddle http://sqlfiddle.com/#!9/69feb5/1

CREATE TABLE memstatus (
  member_id INT,
  date_assigned DATE,
  status_type VARCHAR(10));


INSERT INTO memstatus (member_id, date_assigned, status_type)
VALUES
(178,   '1948-01-01',   'Active'),
(178,   '2015-02-12',   'Deceased'),

(190,   '2013-12-09',   'Active'),
(190,   '2014-03-23',   'Resigned'),
(190,   '2015-12-09',   'Active'),

(194,   '2013-01-01',   'Active'),
(194,   '2015-03-15',   'Lapsed'),
(194,   '2015-08-20',   'Active'),

(935,   '2015-04-01',   'Active'),

(214,   '1966-01-01',   'Active'),
(214,   '2015-01-09',   'Lapsed'),
(214,   '2015-08-10',   'Deceased')

(300,   '2015-01-09',   'Active'),
(300,   '2015-07-10',   'Resigned')

该数据的结果应该是

2015 年加入者

id 190 {2015 年之前离开但 2015 年重新加入}

id 935 {2015年新成员}

2015 年毕业生

id 178 {2015年离开记录}

id 214 {2015 年连续两次离职记录 - 但必须算作一次}

既不是离开者也不是加入者

id 194 {离开但同年重新加入}

id 300 {同年入离}

我为离开者尝试了以下方法(请参阅 SQLfiddle http://sqlfiddle.com/#!9/69feb5/1)但这仅在最后一条记录是离开记录时才有效,因此也给我成员 300。我和木匠有同样的问题。

SELECT member_id, status_type, date_assigned
FROM memstatus
WHERE date_assigned = (SELECT MAX(date_assigned) 
                                    FROM memstatus AS T1 
                                    WHERE T1.member_id = memstatus.member_id 
                                    AND   T1.date_assigned BETWEEN CONCAT('2015','-01-01') AND CONCAT('2015','-12-31')
                                    )

 AND  status_type NOT LIKE 'Active'

SELECT member_id, assigned_year, CASE WHEN finalStatus <0 THEN 'Leaver' WHEN finalStatus >0 THEN 'Joiner' WHEN finalStatus =0 THEN 'Neither' END FROM (Select member_id, Year(date_assigned) AS assigned_year, SUM(CASE WHEN status_type_id = 'Active' THEN 1 WHEN status_type = 'Resigned' THEN -1 WHEN status_type = 'Lapsed' THEN -1 WHEN status_type = 'Deceased' THEN -1 END) AS finalStatus FROM memstatus GROUP BY member_id, Year(date_assigned) ) As a ORDER BY member_id