求助:Impala中实现员工单邮箱取值、多邮箱置空的SQL查询
解决Impala中员工邮箱查询的问题
我来帮你搞定这个查询!你的需求很明确:获取所有员工数据,仅当员工只有一个邮箱时显示该邮箱,多个邮箱则显示null。咱们先看看你原SQL里的几个问题,再给出正确的写法。
原SQL的问题分析
- 未引入
adr表:你的查询里用到了adr.email_addr,但adr这个别名对应的Emailadress表根本没出现在FROM或JOIN子句中,这会直接触发语法错误。 - 子查询缺少分组:子查询
(SELECT employee_id, email_addr, count(*) qty FROM Emailadress HAVING count(*) > 1)里使用了聚合函数count(*),但没有GROUP BY employee_id, email_addr,Impala会因为非聚合字段未分组而报错。 - 分组逻辑错误:你需要先按员工统计邮箱总数,再基于这个总数判断是否显示邮箱,而不是直接按员工和邮箱分组。
正确的查询写法
这里提供两种在Impala中可以正常运行的方案,你可以根据实际情况选择:
方案1:使用窗口函数(更简洁)
窗口函数可以直接计算每个员工的邮箱总数,无需额外分组:
SELECT DISTINCT emp.employee_id, CASE WHEN COUNT(ea.email_addr) OVER (PARTITION BY emp.employee_id) = 1 THEN ea.email_addr ELSE NULL END AS email_address FROM Employee emp LEFT JOIN Emailadress ea ON emp.employee_id = ea.employee_id;
COUNT(ea.email_addr) OVER (PARTITION BY emp.employee_id):计算每个员工关联的邮箱总数DISTINCT:确保每个员工只返回一行结果(如果员工有多个邮箱,会生成多行,去重后保留一行)
方案2:先统计邮箱数量再关联(更直观)
先通过子查询统计每个员工的邮箱数,再关联邮箱表进行判断:
SELECT emp.employee_id, MAX(CASE WHEN cnt.email_count = 1 THEN ea.email_addr ELSE NULL END) AS email_address FROM Employee emp LEFT JOIN ( SELECT employee_id, COUNT(*) AS email_count FROM Emailadress GROUP BY employee_id ) cnt ON emp.employee_id = cnt.employee_id LEFT JOIN Emailadress ea ON emp.employee_id = ea.employee_id GROUP BY emp.employee_id;
- 子查询
cnt:统计每个员工的邮箱总数 MAX(...):如果员工只有一个邮箱,取该邮箱值;如果有多个,所有CASE返回null,MAX(null)仍为null,确保每个员工一行结果
这两种方案都能满足你的需求,在Impala中可以正常执行。
内容的提问来源于stack exchange,提问作者Pallavi
相关产品推荐
相关产品推荐

