计算SQL Server中的连续项

时间:2010-03-22 18:06:41

标签: sql-server-2005 tsql

我正在尝试编写的查询出现问题。我有一张表格,列出了已发送电子邮件的人。有一个名为Active的列,如果它们已响应,则设置为true。但是,我需要计算自第一封电子邮件或上一封有效电子邮件以来该人一直处于非活动状态的连续电子邮件数量。

例如,这个基本表显示一个人已经发送了9封电子邮件。他们在两封电子邮件中都很活跃(3& 5)。所以他们的非活动计数将是4,因为我们从6号电子邮件开始计算。

PersonID(int)    EmailID(int)    EmailDate(datetime)    Active(bit)
1                1               2009-07-18 19:56:20    0
1                2               2009-08-18 19:56:20    0
1                3               2009-09-18 19:56:20    1
1                4               2009-10-18 19:56:20    0
1                5               2009-11-18 19:56:20    1
1                6               2009-12-18 19:56:20    0
1                7               2010-01-18 19:56:20    0
1                8               2010-02-18 19:56:20    0
1                9               2010-03-18 19:56:20    0

任何指针或帮助都会很棒。

此致 格雷格

3 个答案:

答案 0 :(得分:1)

我的第一次切入:

SELECT PersonID, COUNT(*) FROM Table T1
WHERE Active = 0 AND EmailDate > 
   (SELECT MAX(EMailDate) FROM Table T2 
       WHERE T2.PersonID = T1.PersonID AND Active = 1)
GROUP BY PersonID

请注意,此解决方案要求每个人至少回复一封电子邮件。如果您想要从发送给他们的第一封电子邮件中包含非活动状态的人,您需要将(MAX(EmailDate))术语包含在某种IFNULL()中,在系统开始日期之前返回NULL以获取NULL

另外,正如KM指出的那样,如果某人当前没有处于非活动状态(他们回答了最新的电子邮件),他们将不在结果集中。我认为这可能符合您的需求,但如果没有,请告诉我。

答案 1 :(得分:0)

尝试一下:

SET NOCOUNT ON
DECLARE @Emails table (PersonID int, EmailID int,  Active bit)
INSERT @Emails VALUES ( 1,1,0)
INSERT @Emails VALUES ( 1,2,0)
INSERT @Emails VALUES ( 1,3,1)
INSERT @Emails VALUES ( 1,4,0)
INSERT @Emails VALUES ( 1,5,1)
INSERT @Emails VALUES ( 1,6,0)
INSERT @Emails VALUES ( 1,7,0)
INSERT @Emails VALUES ( 1,8,0)
INSERT @Emails VALUES ( 1,9,0)
INSERT @Emails VALUES ( 2,1,0)
INSERT @Emails VALUES ( 2,2,0)
INSERT @Emails VALUES ( 2,3,0)
INSERT @Emails VALUES ( 2,4,0)
INSERT @Emails VALUES ( 2,5,0)
INSERT @Emails VALUES ( 2,6,0)
INSERT @Emails VALUES ( 3,1,1)
INSERT @Emails VALUES ( 3,2,1)
INSERT @Emails VALUES ( 3,3,1)
INSERT @Emails VALUES ( 3,4,1)
SET NOCOUNT OFF


SELECT
    e.PersonID,COUNT(e.EmailID) AS CountInactive
    FROM @Emails e
        LEFT OUTER JOIN (SELECT
                             PersonID,MAX(EmailID) AS LastActive
                             FROM @Emails
                             WHERE Active=1
                             GROUP BY PersonID
                        ) dt ON e.PersonID=dt.PersonID
    WHERE e.EmailID>ISNULL(dt.LastActive,0)
    GROUP BY e.PersonID

输出:

PersonID    CountInactive
----------- -------------
1           4
2           6

(2 row(s) affected)
OP编辑后

编辑,输出与上述相同:

SELECT
    e.PersonID,COUNT(e.EmailID) AS CountInactive
    FROM @Emails e
        LEFT OUTER JOIN (SELECT
                             PersonID,MAX(EmailDate) AS LastActive
                             FROM @Emails
                             WHERE Active=1
                             GROUP BY PersonID
                        ) dt ON e.PersonID=dt.PersonID
    WHERE (e.EmailDate>ISNULL(dt.LastActive,0)) OR dt.PersonID IS NULL
    GROUP BY e.PersonID

答案 2 :(得分:0)

@ Larry-Lustig的答案版本使用COALESCE为没有电子邮件的用户返回计数:

SELECT PersonID, COUNT(*) FROM Table T1
WHERE Active = 0 AND EmailDate > 
   COALESCE (
       (SELECT MAX(EMailDate) FROM Table T2 
           WHERE T2.PersonID = T1.PersonID AND T2.Active = 1),
       DATEFROMPARTS(1900,1,1))
GROUP BY PersonID