计算列中的特定子字符串文本

时间:2014-01-23 13:12:22

标签: sql database excel hive average

我有一个名为'UK.Choices'的Hive表,其中一列标题为'Fruit',每行如下:

AppleBananaAppleOrangeOrangePears

BananaKiwiPlumAppleAppleOrange

KiwiKiwiOrangeGrapesAppleKiwi

等。

有2.5M行,行比上面的长得多。

我想计算“Apple”这个词出现的实例数。 例如,上面是:

'Apple'的数量= 5

到目前为止我的sql是:

  select 'Fruit' from UK.Choices 

然后在300,000块中我复制并粘贴到Excel中,在那里我更精通并且能够使用公式来做到这一点。问题是,生成300,000行的每个块需要一个半小时。

任何人都知道绕过Excel更快捷的方法吗?我可以做一些简单的事情,比如使用where子句的计数,但是像上面这样的东西现在有点超出我的意义。请帮忙。

谢谢。

4 个答案:

答案 0 :(得分:2)

我想我已经晚了2年。但是,既然我正在寻找相同的答案,我终于设法解决了,我认为在这里发布它是一个好主意。

我是这样做的。

解决方案1:

+-----------------------------------+---------------------------+-------------+-------------+  
|              Fruits               |        Transform 1        | Transform 2 | Final Count |  
+-----------------------------------+---------------------------+-------------+-------------+  
| AppleBananaAppleOrangeOrangePears | #Banana#OrangeOrangePears | ##          |           2 |  
| BananaKiwiPlumAppleAppleOrange    | BananaKiwiPlum##Orange    | ##          |           2 |  
| KiwiKiwiOrangeGrapesAppleKiwi     | KiwiKiwiOrangeGrapes#Kiwi | #           |           1 |  
+-----------------------------------+---------------------------+-------------+-------------+  

以下是代码:

SELECT length(regexp_replace(regexp_replace(fruits, "Apple", "#"), "[A-Za-z]", "")) as number_of_apples  
FROM fruits;

您的fruits列中可能包含数字或其他特殊字符,您只需修改第二个正则表达式即可。请记住,在hive中要逃避角色,您可能需要使用\\而不只是\

解决方案2:

SELECT size(split(fruits,"Apple"))-1 as number_of_apples
FROM fruits;

这只是第一个split字符串使用" Apple"作为分隔符并创建一个数组。 size函数只是告诉该数组的大小。请注意,数组的大小比分隔符的数量多一个。

答案 1 :(得分:1)

我认为您希望在一个选择中运行,并使用Hive if UDF来汇总不同的情况。像下面这样......

select sum( if( fruit like '%Apple%' , 1, 0 ) ) as apple_count,
       sum( if( fruit like '%Orange%', 1, 0 ) ) as orange_count
from UK.Choices
where ID > start and ID < end;

而不是上述查询中的连接。

答案 2 :(得分:1)

如果在水果名称之间有任何分隔符(例如:逗号),这是直截了当的。我们的想法是将列拆分为一个数组,并使用'explode'函数将数组分解为多行。

SELECT fruit, count(1) as count FROM 
( SELECT 
     explode(split(Fruit, ',')) as fruit 
  FROM UK.Choices ) X
GROUP BY fruit

从您的示例中,看起来水果是由大写字母分隔的。一个想法是基于大写字母拆分列,假设没有具有相同后缀的水果。

SELECT fruit_suffix, count(1) as count FROM 
( SELECT 
     explode(split(Fruit, '[A-Z]')) as fruit_suffix 
  FROM UK.Choices ) X
WHERE fruit_suffix <> ''
GROUP BY fruit_suffix

缺点是,输出不会有水果的第一个字母,

pple - 5
range - 4 

答案 3 :(得分:0)

没有Hive的经验,我很害怕,所以这可能会也可能不会起作用。但是在SQLServer,Oracle等上我会做这样的事情:

假设你在行上有一个名为ID的int PK,那就是:

select AppleCount, OrangeCount, AppleCount - OrangeCount score
from
(
    select count(*) as AppleCount
    from UK.Choices
    where ID > start and ID < end
    and Fruit like '%Apple%'
) a,
(
    select count(*) as OrangeCount
    from UK.Choices
    where ID > start and ID < end
    and Fruit like '%Orange%'
) o

当电子表格中包含所有行并且可以在那里计算时,我会将除数除以总计数到最后。

但是,我迫切地要求我的老板让我将Fruit字段更改为一个带有FK to Choices和每行一个水果名称的表。除非这是你在Hive中无法做到的事情,否则这种设计会让小猫哭泣。

PS我错过了你想要Apple的出现次数,这是不行的。我正在离开我的答案,因为我认为我的但是... para实际上是一个很好的答案。 :(