Forum Webscript.Ru

Общие => Базы данных => Тема начата: Phoinix от 29 Июня 2004, 18:09:08

Название: Исключение выборки из двух таблиц
Отправлено: Phoinix от 29 Июня 2004, 18:09:08
Есть 2 таблицы:
1. Таблица, в которой одним из полей является число
2. Таблица, в которой 2 поля: минимальное число, максимальное число.

Вторая таблица - список диапазонов чисел для первой таблицы.

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

При попытке запустить запрос:

SELECT t3.param1, count(t3.param1)
FROM table1 AS t1, table2 AS t2, table1 AS t3
WHERE t1.num >= t2.start_num AND
t1.num <= t2.end_num
AND t1.num <> t3.num
GROUP BY t3.num

База уходит в грубокий транс, и возвращается к жизни только остановкой процесса... :(
Видимо неправильно построена логика, но как её сделать правильно, желательно одним запросом???

P.S. совсем забыл - MySQL 4.0.x

еще P.S.
Запрос:

SELECT t1.param1, count(t1.param1)
FROM table1 AS t1, table2 AS t2
WHERE t1.num < t2.start_num AND
t1.num > t2.end_num
GROUP BY t1.num

Ничего не выдает...
Название: Исключение выборки из двух таблиц
Отправлено: Макс от 29 Июня 2004, 19:51:22
могу предложить такой вариант
1. SELECT COUNT(*) FROM table2;
получим кол-во записей во второй таблице ($counts)

2.
SELECT t1.id, t1.num, COUNT(t1.id) as counts
FROM table1 t1,  table2 t2
WHERE t1.num NOT BETWEEN t2.min AND t2.max
GROUP BY t1.id
HAVING counts = $counts;
Название: Исключение выборки из двух таблиц
Отправлено: Phoinix от 29 Июня 2004, 20:09:41
Макс
Нет... немного не так...

Есть таблица логов:
id | remote host | ...

Есть таблица диапазонов:

remote_host_min | remote_host_max | ...

Нужно сделать выборку всех записей из таблицы логов remote_host которых не соответствует ни одному из диапазонов второй таблицы

Выбрать все которые попадают - просто, а вот наоборот - неполучается
Название: Исключение выборки из двух таблиц
Отправлено: Макс от 29 Июня 2004, 20:11:35
а мой метод что возвращает ?
Название: Исключение выборки из двух таблиц
Отправлено: Phoinix от 29 Июня 2004, 20:11:37
Макс
Цитировать
SELECT t1.id, t1.num, COUNT(t1.id) as counts
FROM table1 t1,  table2 t2
WHERE t1.num NOT BETWEEN t2.min AND t2.max
GROUP BY t1.id
HAVING counts = $counts;


Формирует список в 20 раз больше исходного... :(

Только GROUP BY не по id а по num

Даже если точнее: количество записей есть произведение количества записей первой таблицы и количества записей второй таблицы...
Название: Исключение выборки из двух таблиц
Отправлено: Макс от 29 Июня 2004, 20:13:15
remote_host - это IP в виде числа ? (INET_ATON(\'$ip\') ?)
Название: Исключение выборки из двух таблиц
Отправлено: Phoinix от 29 Июня 2004, 20:14:33
Макс
Нет... извиняюсь... обычный varchar

Если в смысле что 192.168.0.1 - то да....
Название: Исключение выборки из двух таблиц
Отправлено: Макс от 29 Июня 2004, 20:14:55
Цитировать
Phoinix:
Только GROUP BY не по id а по num
num == remote_host ? или я вообще смісла полей не пойму
Название: Исключение выборки из двух таблиц
Отправлено: Макс от 29 Июня 2004, 20:16:08
лучше покажи реальный
SHOW CREATE TABLE table1

а то я сейчас просто гадаю
Название: Исключение выборки из двух таблиц
Отправлено: Макс от 29 Июня 2004, 20:17:26
ты вообще понял смысл моего запроса ?
Название: Исключение выборки из двух таблиц
Отправлено: Phoinix от 29 Июня 2004, 20:21:43
CREATE TABLE `access_log` (
  `id` bigint(20) NOT NULL auto_increment,
  `agent` varchar(255) default NULL,
  `bytes_sent` int(10) unsigned default NULL,
  `child_pid` smallint(5) unsigned default NULL,
  `cookie` varchar(255) default NULL,
  `machine_id` varchar(25) default NULL,
  `request_file` varchar(255) default NULL,
  `referer` varchar(255) default NULL,
  `remote_host` varchar(50) default NULL,
  `remote_logname` varchar(50) default NULL,
  `remote_user` varchar(50) default NULL,
  `request_duration` smallint(5) unsigned default NULL,
  `request_line` varchar(255) default NULL,
  `request_method` varchar(10) default NULL,
  `request_protocol` varchar(10) default NULL,
  `request_time` varchar(28) default NULL,
  `request_uri` varchar(50) default NULL,
  `request_args` varchar(255) default NULL,
  `server_port` smallint(5) unsigned default NULL,
  `ssl_cipher` varchar(25) default NULL,
  `ssl_keysize` smallint(5) unsigned default NULL,
  `ssl_maxkeysize` smallint(5) unsigned default NULL,
  `status` smallint(5) unsigned default NULL,
  `time_stamp` int(10) unsigned default NULL,
  `virtual_host` varchar(50) default NULL,
  PRIMARY KEY  (`id`)
) TYPE=MyISAM;

Это логи апача, но в базе данных... (Индексы еще не расставлял, пока не определился какие)

CREATE TABLE `list_hosts` (
  `id` int(11) NOT NULL auto_increment,
  `start_ip` varchar(100) NOT NULL default \'\',
  `end_ip` varchar(100) NOT NULL default \'\',
  `lan` varchar(100) NOT NULL default \'\',
  `primech` varchar(100) NOT NULL default \'\',
  PRIMARY KEY  (`id`)
) TYPE=MyISAM;

Это таблица диапазонов, мне нужно просто убрать

Соответственно, привязка идет по remote_host и start_ip <->end_ip
Название: Исключение выборки из двух таблиц
Отправлено: Phoinix от 29 Июня 2004, 20:25:15
Макс
Цитировать
ты вообще понял смысл моего запроса ?


Не совсем... я не понял, зачем количество записей второй таблицы...
Название: Исключение выборки из двух таблиц
Отправлено: Phoinix от 29 Июня 2004, 20:29:50
Макс
Смысл вообщем какой... вычислить количество (и откуда) не местных заходов... у меня есть диапазоны IP адресов местных провайдеров... я просто хочу исключить (временно) их из общего списка...
Название: Исключение выборки из двух таблиц
Отправлено: Phoinix от 29 Июня 2004, 20:38:37
Phoinix
Цитировать
ты вообще понял смысл моего запроса ?


Все дошло... спасибо ;)
Название: Исключение выборки из двух таблиц
Отправлено: Phoinix от 30 Июня 2004, 14:17:42
Все... разобрался... :)

1. SELECT COUNT(*) FROM main_hosts;

Результат $counts;

2. SELECT access_log.remote_host, access_log.agent, MOD(COUNT(access_log.id), $counts) AS repit, COUNT(access_log.id)/$counts AS counts
FROM access_log, main_hosts
WHERE access_log.remote_host NOT BETWEEN main_hosts.start_ip AND main_hosts.end_ip
GROUP BY access_log.remote_host
HAVING repit = 0