基于与 Hive 中的数组比较的聚合列
Posted
技术标签:
【中文标题】基于与 Hive 中的数组比较的聚合列【英文标题】:Aggregate column based on comparison with array in Hive 【发布时间】:2021-07-07 17:18:37 【问题描述】:假设我有一个如下所示的配置单元表:
|ID |CODE |AMT |NEW AMT|
|---|---------------|-----|-------|
|1 |['a','b',,,] |10 | 50 |
|2 |[,,,'a','b'] |20 | 70 |
|3 |[,'c','d','e',]|30 | 20 |
|4 |['p','q',,,] |40 | 20 |
代码列是数组数据类型。它可以有 5 个值,这些值由 ETLjob 填充。这些值以逗号分隔。 我需要在满足以下条件的情况下找到 AMT 列的聚合值:
-
如果代码具有值“a”、“b”,则该 id 的数量值应为零。
如果代码有值'c'、'd'、'e',那么金额中的值应替换为值
那是在新的amt。
如果不符合上述任一条件,则该值应与amt中的值相同。
在此之后,可以取 amt 的总和。所以对于上面给出的表格,sum(amt) 应该是 60。
我一直在努力解决这个问题,因为我是 hql/sql 的新手。 我曾尝试使用 case 语句进行总结,但失败了。 感谢您的任何意见!
【问题讨论】:
【参考方案1】:“代码列是数组数据类型。”
使用带有 case 表达式的 array_contains() 函数:
select t.id, t.code,
case when array_contains(t.code, 'a') and array_contains(t.code, 'b') then 0
when array_contains(t.code, 'c') and array_contains(t.code, 'd') and array_contains(t.code, 'e') then t.new_amt
else t.amt
end AMT
from table_name t
【讨论】:
【参考方案2】:只需使用if else
或case when
让我们用您提供的示例数据创建一个表
CREATE TABLE `table1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`code` longtext NOT NULL,
`amt` int(11) NOT NULL,
`new_amt` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `table1` (`id`, `code`, `amt`, `new_amt`) VALUES
(1, '[\'a\',\'b\',,,]', 10, 50),
(2, '[,,,\'a\',\'b\']', 20, 70),
(3, '[,\'c\',\'d\',\'e\',]', 30, 20),
(4, '[\'p\',\'q\',,,]', 40, 20);
查看表格的样子SELECT * FROM table1
id | code | amt | new_amt |
---|---|---|---|
1 | ['a','b',,,] | 10 | 50 |
2 | [,,,'a','b'] | 20 | 70 |
3 | [,'c','d','e',] | 30 | 20 |
4 | ['p','q',,,] | 40 | 20 |
现在使用if else
来决定值
SELECT
`code`,
IF(
`code` LIKE "%a','b%",
0,
IF(
`code` LIKE "%c','d','e%",
`new_amt`,
`amt` + `new_amt`
)
) AS price
FROM
`table1`
结果:
id | code | price |
---|---|---|
1 | ['a','b',,,] | 0 |
2 | [,,,'a','b'] | 0 |
3 | [,'c','d','e',] | 20 |
4 | ['p','q',,,] | 60 |
【讨论】:
以上是关于基于与 Hive 中的数组比较的聚合列的主要内容,如果未能解决你的问题,请参考以下文章
为啥我无法在 Hive 中使用具有多个插入子句的高级聚合功能?