0

我一直在绞尽脑汁想如何在没有 PHP 代码的情况下在一个查询中做到这一点。

简而言之,我有一个记录电子邮件活动的表。为了这个例子,这里是数据:

recipient_id     activity     date
1                delivered    2011-08-30
1                open         2011-08-31
2                delivered    2011-08-30
3                delivered    2011-08-24
3                open         2011-08-30
3                open         2011-08-31

目标:我想向用户显示一个数字,告诉用户有多少收件人在 24 小时内打开了他们的电子邮件。

EG“在 24 小时内打开电子邮件的用户:13 位读者”

在上述示例数据的情况下,该值将是“1”。(收件人 1 收到一封电子邮件并在第二天打开它。收件人 2 从未打开它,收件人 3 等了 5 天。)

谁能想到在单个查询中表达目标的方法?

提醒:为了计算,此人必须有一个“已交付”标签和至少一个“打开”标签。每个“打开”标签对每个收件人只计算一次。

** 编辑 ** 抱歉,我使用的是 MySQL

4

3 回答 3

2

这是mysql中的一个版本。

select count(distinct recipient_id)
from email e1
where e1.activity = 'delivered'
  and exists
        (select * from email e2
         where e1.recipient_id = e2.recipient_id
           and e2.activity = 'open'
           and datediff(e2.action_date,e1.action_date) <= 1)

基本原则是,您希望为在 24 小时内也有打开的收件人找到已交付的行。

datediff()是在 mysql 中进行日期算术的好方法——其他数据库将在此步骤的确切方法上有所不同。其余的 sql 将在任何地方工作。

SQLFiddle在这里: http ://sqlfiddle.com/#!2/c9116/4

于 2012-09-01T03:05:01.880 回答
0

未经测试,但应该可以工作;)不知道您使用哪种 SQL 方言,所以我使用了 TSQL DATEDIFF函数。

select distinct opened.recipient_id -- or count(distinct opened.recipient_id) if you want to know number
from actions as opened 
inner join actions as delivered 
on opened.recipient_id = delivered.recipient_id and delivered.activity = 'delivered'
where opened.activity = 'open' and DATEDIFF(day, delivered.date, opened.date) <= 1

编辑:我把打开和交付混淆了 - 现在被替换了。

于 2012-09-01T03:03:07.803 回答
0

假设:MySql,表名为“TABLE”

好的,我不是 100% 的,因为我没有表的副本来运行它,但我认为你可以做这样的事情:

SELECT COUNT(DISTINCT t1.recipient_id) FROM TABLE t1
INNER JOIN TABLE t2 ON t1.recipient_id = t2.recipient_id AND t1.activity != t2.activity
WHERE t1.activity in ('delivered', 'open') AND t2.activity in ('delivered', 'open')
AND ABS(DATEDIFF(t1.date, t2.date)) = 1

基本上,您将一个表加入到自身上,其中活动不匹配,但接收者 ID 匹配,并且状态为“已交付”或“打开”。您最终会得到的结果如下所示:

1 delivered 2011-08-30 1 open 2011-08-31

然后,您将在两个日期之间进行差异(使用绝对值,因为我们不知道它们将处于哪个顺序)并确保它等于 1(或 24 小时)。

于 2012-09-01T03:04:06.930 回答