令人困惑的MySqL加入

时间:2018-05-15 04:09:42

标签: mysql join left-join

不幸的是,我不确定我试图编写的查询是否有特定的名称。我的问题如下,我创建了两个临时表,其中一个表列出了通过IVR或通过电子邮件“选择退出”通信的客户。

mysql> desc tt_customers;
+------------------+------------------+------+-----+---------+-------+
| Field            | Type             | Null | Key | Default | Extra |
+------------------+------------------+------+-----+---------+-------+
| id               | int(10) unsigned | NO   | MUL | 0       |       |
| name             | varchar(40)      | NO   |     | NULL    |       |
+------------------+------------------+------+-----+---------+-------+

mysql> desc tt_opt_outs;
+-----------------------+----------------------------------------+------+-----+---------+-------+
| Field                 | Type                                   | Null | Key | Default | Extra |
+-----------------------+----------------------------------------+------+-----+---------+-------+
| customer_id           | int(10) unsigned                       | NO   | MUL | NULL    |       |
| event_type            | enum('PRE_PEAK_TIME','POST_PEAK_TIME'  | YES  |     | NULL    |       |
| notification_channel  | enum('EMAIL','IVR')                    | NO   |     | NULL    |       |
+-----------------------+----------------------------------------+------+-----+---------+-------+

并非客户表中的所有客户都在选择退出表中。选择退出表中的客户可以选择退出EMAIL,IVR或两者,以及任何事件类型。我想创建一个包含以下列标题customer_idnameIVR OptoutEmail Optout的报告,其中IVR和电子邮件选择退出列无论选项如何出event_type。我不知道如何构建一个join / subquery / union或者我在这里需要的任何东西来创建我需要的确切查询。任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:1)

除了case语句,您还可以使用left outer join。

查询(左外连接)

 select c.id as customer_id , c.name,ti.notification_channel as IVR,
    te.notification_channel as EMAIL from tt_customers c
    left outer join tt_opt_outs ti on c.id = ti.customer_id and ti.notification_channel = 'IVR' 
   left outer join tt_opt_outs te on c.id = te.customer_id and te.notification_channel = 'EMAIL'

<强>输出:

enter image description here

数据设置:

create table tt_customers (id int(10), name varchar(40));
create table tt_opt_outs (customer_id int(10), event_type enum('PRE_PEAK_TIME','POST_PEAK_TIME'), notification_channel enum('EMAIL','IVR') );
insert into tt_customers values (1,"all in");
insert into tt_customers values(2,"email out");
insert into tt_customers values(3,"ivr out");
insert into tt_customers values(4,"all out");
insert into tt_opt_outs values(2,'PRE_PEAK_TIME','EMAIL');
insert into tt_opt_outs values(3,'PRE_PEAK_TIME','IVR');
insert into tt_opt_outs values(4,'PRE_PEAK_TIME','EMAIL');
insert into tt_opt_outs values(4,'PRE_PEAK_TIME','IVR');

SQL小提琴:http://sqlfiddle.com/#!9/0e82a7/17

答案 1 :(得分:0)

以下是将为您提供所需结果的SQL:

create table tt_customers(id int,name varchar(40));
create table tt_opt_outs(customer_id int,event_type enum('PRE_PEAK_TIME','POST_PEAK_TIME'),notification_channel enum('EMAIL','IVR'));

insert into tt_customers values(1,'ABC');
insert into tt_customers values(2,'XYZ');
insert into tt_opt_outs values(1,'PRE_PEAK_TIME','EMAIL');
insert into tt_opt_outs values(2,'POST_PEAK_TIME','IVR');

您对所需结果的查询:

select c.id as customer_id,
    c.name,
    case when t.notification_channel = 'IVR' then 'Yes' else null end ivr_optout,
    case when t.notification_channel = 'EMAIL' then 'Yes' else null end email_optout
from tt_customers c
   left join tt_opt_outs t
   on (c.id = t.customer_id);