|
|
|
| Итак, есть статистика посещяемости сайта, выводимая из базы SQL.
Вывод происходит из двух таблиц синхронно.
Вывод статистики выглядит так:
1 172.25.18.24 %unkmow% 7
2 172.25.18.23 MaJIbILLI 392
3 172.25.18.18 %unkmow% 125
4 172.25.18.16 MAD 801
5 172.25.18.12 %unkmow% 1
6 172.25.112.60 %unkmow% 1
|
Первая колонка - порядковый номер (значение не имеет, т.к. берется не из базы sql)
Вторая колонка - IP пользователя
Третяя колонка - Имя пользователя (Выполняется проверка в другой таблице, на совпадение с IP из второй колонки, если оно есть, то выводится соответствующее имя)
Четвертая колонка - Количество посещений.
Итак, в первой таблице хранятся данные о посещениях.
Из этих данных требуется только IP посетителя.
И сколько раз этот IP встречается в этой таблице (т.е сколько раз этот пользователь посещал данную страницу.)
Во второй таблице хранится информация об именах пользователей.
В ней записан IP и имя пользователя с этим IP.
===========================================================
Так работает мой вариант статистики:
1. Выполняется запрос на получение всех уникальных IP адресов из первой таблицы.
$get_ip_list=mysql_query("SELECT DISTINCT `ip` FROM `post` ORDER BY `ip` DESC;")
|
2. Теперь, поcредством PHP функции mysql_fetch_array() выполняется пробег по всем полученным IP адресам
$ire=0;
while($ip_list_array=mysql_fetch_array($get_ip_list))
{
$ire++;
#дальнейшие интрукции
}
|
3. Итак, получив IP адрес, нужно для каждого определить сколько раз он встречается в первой таблице и получить имя пользователя с этим IP из второй таблицы. Это и есть " #дальнейшие интрукции"
//Получаем количество посещений для IP:
$visitings=mysql_num_rows(mysql_query("SELECT `number` FROM `post` WHERE `ip` LIKE '".$ip_list_array[0]."';"));
//Попытка получить имя для IP из второй таблицы:
$user_name_a=mysql_fetch_array(mysql_query("SELECT `name` FROM `users` WHERE `ip` LIKE '".$ip_list_array[0]."';"));
//Дальше, выполняется проверка существует ли совпадение с IP во второй таблице.
//Если совпадения нет то выведется %unkmow%, если есть, то выведется то, что было найдено во
//второй таблице.
if(isset($user_name_a[0])){$user_name=$user_name_a[0];}else{$user_name="%unkmow%";}
echo "<tr><td>$ire</td><td>$ip_list_array[0]</td><td>$user_name</td><td>$visitings</td></tr>\n";
|
Так работает мой вариант.
Но он очень громозкий. Его надо упростить, потому что выполняется очень медленно.
========================================================================
Итак, я жду ваших предложений по упрощению конструкции этого кода.
Заранее благодарен. | |
|
|
|
|
|
|
|
для: Dr Lines
(09.12.2008 в 08:01)
| | 1. Для сравнения значений LIKE не применяют.
2. Чтобы получить число строк в таблице, запрашивают именно число строк, а не сами строки.
3. оба запроса можно было бы переписать в один, если ip для второй таблицы - уникальный ключ.
SELECT post.ip AS pip, MAX(users.name) as nm, COUNT(*) AS cnt
FROM post JOIN users ON post.ip = users.ip
GROUP BY pip
|
| |
|
|
|
|
|
|
|
для: Trianon
(09.12.2008 в 10:28)
| | если ip для второй таблицы - уникальный ключ
Как прикажете понимать?)) Мне казалось по поводу ip у вас пунктик)) | |
|
|
|
|
|
|
|
для: Valick
(09.12.2008 в 10:45)
| | А что непонятно?
Если в таблице users поле ip уникальным не является, то name в запросе оказывается неоднозначным уже не формально (для чего я собственно и написал MAX()), а фактически.
По поводу пунктика, если можно, раскажите поподробнее. | |
|
|
|
|
|
|
|
для: Trianon
(09.12.2008 в 10:59)
| | По поводу уникального поля и самого запроса всё понятно.
По поводу пунктика, позвольте процитировать
автор: Trianon (27.08.2007 в 22:00) письмо автору
для: kasmanaft (27.08.2007 в 20:07)
не трогайте IP. Оно не Ваше.
|
Вы всегда являлись ярым противником уникальности IP. Так и есть много пользователей могут иметь один и тот-же IP. | |
|
|
|
|
|
|
|
для: Valick
(09.12.2008 в 11:17)
| | Конечно, мне это не нравится.
Но, по-моему, вопросов проектирования автор не ставил.
Поэтому я решил в бутылку не лезть. | |
|
|
|
|
|
|
|
для: Valick
(09.12.2008 в 11:17)
| | Этот код расчитан на работу в локальной сети, в которй у всех уникальные IP адреса. | |
|
|
|
|
|
|
|
для: Dr Lines
(09.12.2008 в 12:07)
| | у кого у всех? ))) | |
|
|
|
|
|
|
|
для: Trianon
(09.12.2008 в 12:18)
| | Я сказал локальной сети, а не интернета.
А подменить IP на чужой в ней не получится (даже если сменить mac-адрес), уж так она устроена.
Вобщем это не касается данного вопроса. Так что забудем.
Да, кстати ваш код выдает ошибку здесь:
MAX(users.name)
#1054 - Unknown column 'users.name' in 'field list'
хотя таблица users существует и столбец с заголовком name у неё тоже присутствует. | |
|
|
|
|
|
|
|
для: Dr Lines
(09.12.2008 в 12:51)
| | проверяйте. У меня этот запрос выполняется нормально. | |
|
|
|
|
|
|
|
для: Trianon
(09.12.2008 в 13:07)
| | Вобщем поковырялся и сделал рабочий вариант:
SELECT `users`.`ip` AS `ip`, `users`.`name` AS `name`,
COUNT(*) AS `count`
FROM `post` JOIN `users`
WHERE `post`.`ip` ='172.16.70.11'
AND `post`.`ip` = `users`.`ip`
GROUP BY `users`.`name` ASC ;
|
| |
|
|
|
|
|
|
|
для: Trianon
(09.12.2008 в 13:07)
| | Мде, упростить - упростили, а на скорость выполнения это никак не повлияло. (больше 90 секунд выполняет при таблице с 80ю тысячами записями.)
Видимо надо свеси всё до 1го запроса. Тобишь и DISTINCT(`ip`) и все остальное. Буду ломать голову дальше..... | |
|
|
|
|
|
|
|
для: Dr Lines
(09.12.2008 в 13:47)
| | последний запрос делает совершенно не то, что мой.
Впрочем дело Ваше.
индексы на полях ip с и name cтоят? | |
|
|
|
|
|
|
|
для: Trianon
(09.12.2008 в 14:53)
| | Да, у каждой из таблиц есть поле индекс с авто инерементом (`number`), я его тут не описывал.
Что на счет вашего запроса, то получается он выводит только те IP адреса, для которых были найдены имена из второй таблицы. А остальные IP он не выводит.
Надо чтобы запрос вывел все результаты, а у кого найдет имя - и имя вывел тоже. | |
|
|
|
|
|
|
|
для: Dr Lines
(09.12.2008 в 15:23)
| | >Да, у каждой из таблиц есть поле индекс с авто инерементом (`number`), я его тут не описывал.
Вы запрашиваете отбор строк по полю ip . И (непонятно зачем) группировку по name. При чем тут number?
>Надо чтобы запрос вывел все результаты, а у кого найдет имя - и имя вывел тоже.
LEFT JOIN | |
|
|
|
|
|
|
|
для: Trianon
(09.12.2008 в 15:29)
| | Все, проблема решена.
Использовал:
SELECT `post`.`ip` AS `ip`,
MAX(`users`.`name`) AS `name`,
COUNT(*) AS `count` FROM `post` LEFT JOIN `users`
ON `post`.`ip` = `users`.`ip` GROUP BY `ip`;
|
Таблицу из 86497 записей прощитал за 4 секунды.!
Trianon, благодарю за предоставленное решение. | |
|
|
|