我有一个表email_activities_2,其中包含一个标题为“action_type”的列,其中结果可以是“已发送”,“打开”,“点击”等,每个电子邮件,每个recipient_id,每个操作有一条记录。例如,recipient_id 94607 for recipient_id 54有两行:一行是action_type被“发送”,第二行是“打开”。
我想要一个将在一行中返回的查询,其中action_type列列出两次,但在左侧,只显示action_type =“sent”,右列是action_type =“open”或“null”< / p>
这是我最接近我想要的东西:
select email2.email_id, email2.recipient_id, email2.action_type as sent,
opens.action_type as opened
from email_activities_2 email2
left join email_activities_2 opens on email2.id = opens.id
where email2.action_type = "sent"
union all
select email2.email_id, email2.recipient_id, email2.action_type as sent,
opens.action_type as opened
from email_activities_2 email2
right join email_activities_2 opens on email2.id = opens.id
where opens.action_type = "open"
order by recipient_id, email_id asc;
返回:
email_id | recipient_id | sent | opened
94607 54 sent sent
94607 54 open open
94981 54 sent sent
98479 54 sent sent
98479 54 open open
当我想要的是:
email_id | recipient_id | sent | opened
94607 54 sent open
94981 54 sent NULL
98479 54 sent open
这可能吗?我是SQL的新手,并且在我去的时候试图解决这个问题。
答案 0 :(得分:0)
以下SQL应该为您完成这项工作:
Select email2.email_id,
email2.recipient_id,
MAX ( CASE WHEN email2.action_type = "sent" THEN email2.action_type END ) As sent,
MAX (CASE WHEN opens.action_type = "open" THEN opens.action_type END) As opened
from email_activities_2 email2
left join email_activities_2 opens on email2.id = opens.id
where email2.action_type = "sent" or opens.action_type = "open"
group by email2.email_id
order by recipient_id, email_id asc;
答案 1 :(得分:0)
我知道您希望获取所有已发送的电子邮件及其公开活动(如果已打开) 查询应该是:
select email2.email_id, email2.recipient_id, email2.action_type as sent,
opens.action_type as opened
from email_activities_2 email2
left join (
select * from email_activities_2
where email_activities_2.action_type = "open"
) as opens on email2.id = opens.id
where email2.action_type = "sent"
答案 2 :(得分:0)
一种方法是条件聚合,不需要连接。
SELECT e.email_id
, e.recipient_id
, MAX(IF(e.action_type='sent',e.action_type,NULL)) AS sent
, MAX(IF(e.action_type='open',e.action_type,NULL)) AS opened
FROM email_activities_2 e
WHERE e.action_type IN ('sent','open')
GROUP
BY e.email_id
, e.recipient_id
GROUP BY子句将&#34;崩溃&#34;具有相同值的email_id和recipient_id的所有行成为一行。 SELECT子句中表达式中的条件测试将&#34;选择&#34;每个组的'open'
和'sent'
的值。 MAX聚合将选择要返回的最高非NULL值,并且只有在组中没有符合条件的行时才返回NULL。
此查询有可能返回如下行:
email_id | recipient_id | sent | opened
94999 54 NULL open
如果有一行open
但行没有sent
。
如果您需要删除这些行,可以添加一个HAVING子句:
HAVING MAX(IF(e.action_type='sent',e.action_type,NULL)) = 'sent'
如果要从表中返回email_id和recipient的所有值,即使没有action_type为'sent'
或'open'
的行,也可以完全省略WHERE子句。
答案 3 :(得分:0)
如果您只想显示已发送的电子邮件(或该表仅包含已发送的电子邮件),LEFT JOIN解决方案适用于两种类型。
select
sent.email_id,
sent.recipient_id,
sent.action_type as sent,
open.action_type as opened
from email_activities_2 sent
left join email_activities_2 open
on open.email_id = sent.email_id
and open.recipient_id = sent.recipient_id
and open.action_type = 'open'
where sent.action_type = 'sent';