繁体   English   中英

当不存在ID时,SQL从记录值中减去上一行

[英]SQL subtract previous row from record value when no ID exists

我有一个与此处发布的问题类似的问题“ 如何在sql中减去上一行? ”但更为复杂。 某些解决方案使用递增的ID号,我的数据本身没有此编号,但需要时打开添加一个(但需要查询帮助来做到这一点)。 我正在尝试查找每个EACH用户打开电子邮件的平均天数。 我的数据看起来像这样

**Email Address | Open Date |  CampaignName**

Email1@gmail     |  01/01/2013 | WelcomeCampaign
Email1@gmail     |  03/01/2013 | WelcomeCampaign
Email1@gmail     |  05/20/2013 | WelcomeCampaign
Email2@gmail     |  01/16/2013 | WelcomeCampaign
Email2@gmail     |  02/28/2013 | WelcomeCampaign
Email3@gmail     |  01/05/2013 | WelcomeCampaign
Email3@gmail     |  01/10/2013 | WelcomeCampaign
Email3@gmail     |  02/15/2013 | WelcomeCampaign
Email3@gmail     |  03/15/2013 | WelcomeCampaign
Email3@gmail     |  04/02/2013 | WelcomeCampaign

需要获取这样的数据,如果电子邮件地址匹配,则从上一个记录中减去每个日期

**Email Address | Open Date |  CampaignName | DaysBetween**

Email1@gmail     |  01/01/2013 | WelcomeCampaign | NA
Email1@gmail     |  03/01/2013 | WelcomeCampaign | 60
Email1@gmail     |  05/20/2013 | WelcomeCampaign | 80
Email2@gmail     |  01/16/2013 | WelcomeCampaign | NA
Email2@gmail     |  02/28/2013 | WelcomeCampaign | 42
Email3@gmail     |  01/05/2013 | WelcomeCampaign | NA
Email3@gmail     |  01/10/2013 | WelcomeCampaign | 5
Email3@gmail     |  02/15/2013 | WelcomeCampaign | 35
Email3@gmail     |  03/15/2013 | WelcomeCampaign | 30
Email3@gmail     |  04/02/2013 | WelcomeCampaign | 17

然后,我计划平均每个用户(email2 @ gmail为70天)

这样做的方法因数据库(未指定)而异,但是如果LAG()可用,这很容易:

SELECT *,DATEDIFF(day,OpenDate,LAG(OpenDate) OVER(PARTITION BY EmailAddress ORDER BY OpenDate)) As DaysBetween
FROM Table1

如果不可用,您将执行偏移自联接以实现相同目的:

WITH cte AS (SELECT *,ROW_NUMBER() OVER(PARTITION BY EmailAddress ORDER BY OpenDate) AS RN
             FROM Table1)
SELECT a.*,DATEDIFF(day,a.OpenDate,b.OpenDate) AS DaysBetween
FROM cte a
LEFT JOIN cte b
  ON a.EmailAddress = b.EmailAddress
  AND a.RN = b.RN+1

两者的演示: SQL Fiddle

以上之一可以在大多数dbms中使用(当然,在语法上也有所不同),但在MySQL中却不能。

如果要获取两次电子邮件之间的平均天数,则有一种更简单的方法。

select EmailAddress, 
       (case when count(*) > 1 then (max(OpenDate) - Min(OpenDate)) / (count(*) - 1)
        end) as AvgTimeBetweenEmails
from table t
group by EmailAddress;

平均持续时间是最大打开日期减去最小打开日期除以电子邮件数减去1。

至于问题的答案,如果数据库支持, lag()使用lag()函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM