SQL - 需要确定提供的开始日期的隐含结束日期

时间:2011-03-04 14:51:43

标签: sql sql-server-2008

请考虑以下事项:

CREATE TABLE Members 
(
    MemberID CHAR(10)
    , GroupID CHAR(10)
    , JoinDate DATETIME
)

INSERT Members VALUES ('1', 'A', 2010-01-01)
INSERT Members VALUES ('1', 'C', 2010-09-05)
INSERT Members VALUES ('1', 'B', 2010-04-15)
INSERT Members VALUES ('1', 'B', 2010-10-10)
INSERT Members VALUES ('1', 'A', 2010-06-01)
INSERT Members VALUES ('1', 'D', 2001-11-30)

选择此表的最佳方法是,确定隐含的“LeaveDate”,生成以下数据集:

MemberID GroupID JoinDate    LeaveDate
1        A       2010-01-01  2010-04-14
1        B       2010-04-15  2010-05-31
1        A       2010-06-01  2010-09-04
1        C       2010-09-05  2010-10-09
1        B       2010-10-10  2010-11-29
1        D       2010-11-30  NULL

如您所见,假定会员没有成员资格失效。假定每个成员状态期间的[LeaveDate]是可以在不同组中为该成员找到的下一个按时间顺序[JoinDate]的前一天。当然,这是我实际问题的简化说明,其中包括几个分类/分组列以及数千个不同的成员,其中[JoinDate]值没有按特定顺序存储。

2 个答案:

答案 0 :(得分:2)

也许这样的事情?自我加入,并选择大于当前行的加入日期的最小加入日期 - 即休假日期加1。从中减去一天。

您可能需要调整特定RDBMS的日期算法。

SELECT
      m1.*
    , MIN( m2.JoinDate ) - INTERVAL 1 DAY AS LeaveDate
FROM
    Members m1
LEFT JOIN
    Members m2
ON    m2.MemberID = m1.MemberID
AND   m2.JoinDate > m1.JoinDate
GROUP BY
      m1.MemberID
    , m1.GroupID
    , m1.JoinDate
ORDER BY
      m1.MemberID
    , m1.JoinDate

答案 1 :(得分:0)

标准(ANSI)SQL解决方案:

SELECT memberid,
       groupid,
       joindate,
       lead(joindate) OVER (PARTITION BY memberid ORDER BY joindate ASC) AS leave_date
FROM members
ORDER BY joindate ASC