将 A 列的一个值与 Hive HQL 中 B 列的所有值进行比较

Posted

技术标签:

【中文标题】将 A 列的一个值与 Hive HQL 中 B 列的所有值进行比较【英文标题】:Compare one value of column A with all the values of column B in Hive HQL 【发布时间】:2018-04-17 07:35:33 【问题描述】:

我在一个表中有两列,比如 A 列和 B 列。我需要每次都用 B 列的所有值搜索 A 列的每个值,如果在任何一个中找到 A 列值,则返回 true B 列的行。我怎样才能得到这个?

我已尝试使用以下命令:

select column _A, column_B,(if (column_A =column_B), True, False) as test from sample;

如果我使用上述命令,它会单独检查该特定行。但是我需要真实值,如果在 B 列的任何行中找到 A 列的值。 如何检查 A 列的一个值和 B 列的所有值?

或者是否有可能迭代和比较两列之间的每个值?

【问题讨论】:

【参考方案1】:

解决方案

创建临时表 t as select rand() as id, column_A, column_B from sample; --> 参考1

select distinct t3.id,t3.column_A,t3.column_B,t3.match from ( --> 参考3

select t1.id as id, t1.column_A as column_A, t1.column_B as column_B,--> Refer 2 
if(t2.column_B is null, False, True) as match  from t t1 LEFT OUTER JOIN
   t t2  ON t1.column_A = t2.column_B 

) t3;

说明

    创建一个标识符列来跟踪原始表中的行。我在这里使用rand()。我们将利用这一点在第 3 步中获取原始行。在此处创建一个临时表 t 以简化后续步骤。

    使用 LEFT OUTER JOIN 和 self 进行测试,需要在所有行中将每一列与另一列进行匹配,从而产生 match 列。请注意,与Sample 表相比,此处可能会创建多个重复行,但我们已经处理了重复行,因为它们的id 列将是相同的。

    在这一步中,我们应用distinct 来获取Sample 表中的原始行。然后,您可以放弃 id 列。

注意事项

    自联接在性能方面的成本很高,但这对于解决问题是不可避免的。 第 3 步中使用的distinct 也很昂贵。一种更高效的方法是使用窗口函数,我们可以按id 分区并选择窗口中的第一行。你可以探索一下。

【讨论】:

【参考方案2】:

您可以对其自身进行左连接并检查列键是否为空。如果它为空,则在另一个表中找不到该值。使用 if 或 "case when" 函数来检查它是否为空。

Select t1.column_A,
          t1.column_B,
         IF(t2.column_B is null, 'False', 'True') as test
from Sample t1
Left Join Sample t2
On t1.column_A = t2.column_B;

【讨论】:

如果特定的t1.column_At2.column_B 中多次出现,这将产生比Sample 更多的行数

以上是关于将 A 列的一个值与 Hive HQL 中 B 列的所有值进行比较的主要内容,如果未能解决你的问题,请参考以下文章

使用 hql 将列表中的列转换为数组和数组到 hive 中的列表

HQL 左外连接用于查找一个表中存在而其他表中不存在的记录

如何获取 HIVE/PySpark 表中每一列的唯一值?

如何将列的当前值与sql server和Oracle中同一列的先前值进行比较

Hive UDF 全局变量

hive优化总结