2013-08-05 51 views
0

我在配置單元上有兩個表。首先,所謂的「訪問」,包含Apache日誌,其中第一場是一個完整的IP地址:JOIN合成器上的Hive RLIKE

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,計數(access.ip)從接入JOIN客戶WHERE access.ip RLIKE client.ip GROUP BY client.name;

它的工作原理,但對於客戶端A,我得到了我的apache日誌的最後一個條目(192.10.4.177),也是我不想要的。我只想比較一下client.ip和access.ip的開頭。

我想一個特定的正則表達式......或者我的合成器是錯的......有人可以有一個想法嗎?

在此先感謝

回答

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; 

第一\\.意味着一個正則表達式\.(我們需要添加「\」指定「\」,在蜂巢)。第二個\\.表示字符串\.。如果您對Java正則表達式不熟悉,可能會使您感到困惑。

+0

是的!它工作正常,謝謝。順便說一下,CONCAT(和RLIKE也一樣)的使用與MySQL(http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_concat)相同。 –