【问题标题】:Hive with multiple subqueries具有多个子查询的 Hive
【发布时间】:2015-11-24 17:18:15
【问题描述】:

我试图在 where 子句中运行多个子查询,但出现以下错误。是否意味着 Hive 不支持它?如果没有,是否有不同的方式来编写下面的查询?

执行 hive 查询时出错:OK FAILED: SemanticException [Error 10249]: Line 14 Unsupported SubQuery Expression 'adh': 仅支持 1 个子查询表达式。

select
    first_name, 
    last_name,
    salary,
    title,
    department
from 
    employee_t1 emp
where 
    emp.salary <= 100000
    and (
        (emp.code in (select comp from history_t2 where code_hist <> 10))
        or 
        (emp.adh in (select comp from sector_t3 where code_hist <> 50))
    ) 
    and department = 'Pediatrics';

【问题讨论】:

标签: sql hive hiveql


【解决方案1】:

我同意戈登的观点。使用 Joins 您可以尝试以下查询(未测试):

 select
    a.first_name, 
    a.last_name,
    a.salary,
    a.title,
    a.department
from 
    (Select * from employee_t1 where 
    emp.salary <= 100000
    and department = 'Pediatrics') a
left outer join (select comp from history_t2 where code_hist <> 10) b
on a.code = b.comp   
left outer join  (select comp from sector_t3 where code_hist <> 50) c
on a.adh = c.comp
where b.comp is not null
or    c.comp is not null
;

【讨论】:

  • 在子查询中应该是select distinct comp
【解决方案2】:

两个选项。一个是joins,另一个是union all

where emp.salary <= 100000 and
      emp.code in (select comp
                   from history_t2 
                   where code_hist <> 10
                   union all
                   select comp
                   from sector_t3
                   where code_hist <> 50
                  ) and
      emp.department = 'Pediatrics';

通常不建议这样做,因为优化选项较少。但是如果 Hive 有这个限制(而且我还没有在 Hive 中尝试过这种类型的查询),那么这可能是一种解决方法。

如果comp 字段在两个表中是唯一的,那么join 方法将是最合适的。否则,您需要删除重复项以避免join 中的重复。

【讨论】:

    【解决方案3】:

    只是在这里添加一点注释。错误消息指出 hive 仅支持 1 个子查询。这实际上与 hive 的限制有关:“单个查询仅支持一个子查询表达式”。

    您可以参考这里的官方文档。 https://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.6.5/bk_data-access/content/hive-013-feature-subqueries-in-where-clauses.html

    【讨论】:

      【解决方案4】:

      这正是left semi join 的用途:

      select
          distinct main.*
      from
      (
      select
          emp.first_name, 
          emp.last_name,
          emp.salary,
          emp.title,
          emp.department
      from 
          employee_t1 emp
      left semi join 
              (select distinct comp from history_t2 where code_hist <> 10) emp_code on emp_code.comp=emp.code
      where 
          emp.salary <= 100000 and emp.department = 'Pediatrics'
      union all
      select
          emp.first_name, 
          emp.last_name,
          emp.salary,
          emp.title,
          emp.department
      from 
          employee_t1 emp
      left semi join 
              (select distinct comp from sector_t3 where code_hist <> 50) emp_adh on emp_adh.comp=emp.adh
      where 
          emp.salary <= 100000 and emp.department = 'Pediatrics'
      ) main
      

      参考:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Joins

      【讨论】:

      • 假设有一行同时满足codeadh 条件。对于union all,此行将出现两次,但在问题的原始查询中它只会出现一次。使用 union 将有助于删除重复项。如果employee_t1 表有重复,unionunion all 都将失败,distinct main.* 将错误地删除此类重复。
      猜你喜欢
      • 2016-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多