2013-08-05 3 views
0

У меня есть два стола на улей. Первый из них, называемого «доступ», содержит Apache журналов, где первое поле является полным IP-адрес:Улей RLIKE на JOIN synthax

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" 

и другими, называемым «клиентом», который содержит начало диапазона адресов и строки:

10.4 clientA 
10.5 clientB 
10.7 ClientC 

Я бы хотел найти общее количество обращений по клиенту и отобразить их имя. Таким образом, я пытаюсь соединить эти две таблицы, как это:

ВЫБРАТЬ client.name, граф (access.ip) FROM доступа РЕГИСТРИРУЙТЕСЬ клиента ГДЕ access.ip RLIKE client.ip GROUP BY client.name;

Это работает, но для клиента A я получаю удар для последней записи (192.10.4.177) моего журнала apache тоже, чего я не хочу. Я хотел бы сравнить 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). –

 Смежные вопросы

  • Нет связанных вопросов^_^