0

我在蜂巢上有两张桌子。第一个称为“访问”,包含 apache 日志,其中第一个字段是完整的 ip 地址:

10.4.5.12 - - [26/Jun/2010:11:16:09 +1000] "GET /myportal/pageA HTTP/1.1"
10.4.41.2 - - [26/Jun/2010:11:18:09 +1000] "GET /myportal/pageB HTTP/1.1"
10.5.1.111 - - [26/Jun/2010:11:22:09 +1000] "GET /myportal/pageA HTTP/1.1"
192.10.4.177 - - [26/Jun/2010:11:22:41 +1000] "GET /myportal/pageC HTTP/1.1"

另一个叫做“客户端”,它包含一个 IP 范围的开头和一个字符串:

10.4 clientA
10.5 clientB
10.7 ClientC

我想按客户查找点击总数,并显示他们的名字。所以,我尝试像这样加入这两个表:

SELECT client.name, count(access.ip) FROM access JOIN client WHERE access.ip RLIKE client.ip GROUP BY client.name;

它可以工作,但对于clientA,我的apache日志的最后一个条目(192.10.4.177)也受到了打击,这是我不想要的。我想仅将 client.ip 与 access.ip 的开头进行比较。

我想一个特定的正则表达式......或者我的合成器是错误的......有人可以有一个想法吗?

提前致谢

4

1 回答 1

2

RLIKE 使用 Java 正则表达式。所以你可以用“^”来表示以某事开头。例如,您可以使用 'CONCAT("^",client.ip)' 将 "^" 放在client.ip.

SELECT client.name, count(access.ip)
FROM access JOIN client
WHERE access.ip RLIKE CONCAT("^",client.ip)
GROUP BY client.name;

然而,由于“。” 也是正则表达式中的特殊字符,表示任何字符。所以上述解决方案并不完美。例如,如果客户端 ip 是1.3,它可能匹配 '103.2.3.4'。所以一个更好的解决方案是逃避“。” 在客户端 IP。这是最终的解决方案:

SELECT client.name, count(access.ip)
FROM access JOIN client
WHERE access.ip RLIKE CONCAT("^",REGEXP_REPLACE(client.ip, "\\.", "\\."))
GROUP BY client.name;

第一个\\.表示正则表达式\.(我们需要添加“\”来指定 Hive 中的“\”)。第二个\\.表示一个字符串\.。如果您不熟悉 Java 正则表达式,它可能会让您感到困惑。

于 2013-08-06T03:05:21.573 回答