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

SQL-需要为提供的开始日期确定隐式结束日期,sql,sql-server-2008,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 Memb

考虑以下几点:

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)
从该表中选择的最佳方法是什么,确定隐含的“离开日期”,生成以下数据集:

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]可在不同组中找到该成员。当然,这是我实际问题的一个简化说明,其中包括更多的分类/分组列和数千个不同的成员,这些成员的[JoinDate]值没有特定顺序存储。

可能是这样的吗?自动加入,并选择大于当前行加入日期的最小加入日期,即休假日期加一。从中减去一天

您可能需要调整特定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
标准(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 选择memberid, groupid, 联合日期, 领先(joindate)超过(按成员ID划分,按joindate ASC排序)作为休假日期 来自成员 按joindate ASC订购
它们是否都应该具有相同的
成员ID
?如何确定LeaveDate?我是为ANSI标准代码拍摄的,但是MSSQL 2008似乎不支持LEAD()OVER()。谢谢你的建议。看起来是一个非常优雅的解决方案。@Rich.Carpenter:您没有说明您的DBMS以及我使用的所有DBMS支持lead()和lag();)