|
|
|
| Есть таблица ip адресов. Она состоит из столбцов
id_ip, ip, id_author, time
Необходимо выбрать последний IP адрес для каждого автора, и время когда он с него зашел. Помогите пожалуйста.
Пользуюсь следующим запросом
SELECT ip, max(time) as time, id_author FROM ips GROUP BY id_author ORDER BY time DESC;
|
И у меня частенько путаются последние IP адреса. Т.е адрес не соответствует времени. | |
|
|
|
|
автор: arka (03.09.2004 в 15:47) |
|
|
для: Kirill
(03.09.2004 в 11:09)
| | Может быть заменить на
SELECT MAX(ip) AS max_ip, MAX(time) AS max_time, id_auth FROM ips GROUP BY id_auth ORDER BY time DESC | |
|
|
|
|
|
|
|
для: arka
(03.09.2004 в 15:47)
| | Нет, так тоже не получится. Это даст неправильные результаты. | |
|
|
|
|
автор: arka (03.09.2004 в 15:49) |
|
|
для: Kirill
(03.09.2004 в 11:09)
| | только вместо id_auth - id_author | |
|
|
|
|
|
|
|
для: Kirill
(03.09.2004 в 11:09)
| | Мне кажется это не получится сделать одним запросом, учитывая, что вложенные подзапросы MySQL в 3 версии не поддерживает :(
А запрос, да, не работает. Потому что если Вы запрашиваете 3 поля ip, max(time) as time, id_author и одно из них с агрегатной функцией max, то группировка должна идти по 2 оставшимся полям: ip и id_author. А у Вас только по одному GROUP BY id_author.
Поэтому нужно решать эту задачу по другому. Возможно придется переделывать структуру таблицы. Какую задачу Вы хотите решить с помошью этого запроса? Может быть можно ее немного изменить? | |
|
|
|
|
|
|
|
для: glsv (Дизайнер)
(03.09.2004 в 16:40)
| | Хочу вывести последний IP адрес каждого пользователя. И время в которое он вошел под ним.
Приму любые варианты решений ;) | |
|
|
|
|
|
|
|
для: Kirill
(03.09.2004 в 18:25)
| | Сначала воодушивился :))), но эту задачу на MySQL похоже в один запрос не решишь (без вложенных запросов здесь мало чего сделаешь), сначала следует выбрать вторичные ключи авторов и соответствующее им время последнего посещения
SELECT distinct(id_author) AS id_author, max(time) AS max_time FROM ips GROUP BY id_author
|
а затем выбирать соответствующие им IP-адерса:
SELECT * FROM ips WHERE id_author=id_author AND time=max_time
|
Или на PHP:
<?php
$first = mysql_query("SELECT distinct(id_author) AS id_author, max(time) AS max_time FROM ips GROUP BY id_author");
if($first)
{
while($res = mysql_fetch_array($first))
{
$query = "SELECT * FROM ips
WHERE id_author=".$res['id_author']." AND time=".$res['max_time'];
$final = mysql_query($query);
$result = mysql_fetch_array($final);
echo $result['ip']." - ".$result['time']."<br>";
}
}
?>
|
PS Хм... хотя мне кажется это всё можно решить и в один присест :))) объединениями... | |
|
|
|
|
|
|
|
для: cheops
(03.09.2004 в 23:22)
| | Я тоже к этому склоняюсь..., но столько запросов ради одной таблички - не красиво получается :( | |
|
|
|
|
|
|
|
для: cheops
(03.09.2004 в 23:22)
| | спасибо :)
Вот такая вот вышла головоломка. Тест на знание MySQL ;) | |
|
|
|
|
|
|
|
для: cheops
(03.09.2004 в 23:22)
| | Все хорошо, но можно ли все результаты выводить не в этом цикле?
Собрать все это в таблицу MySQL
Я слышал легенду о неких "временных" таблицах ;) | |
|
|
|
|
|
|
|
для: Kirill
(03.09.2004 в 23:58)
| | Обычно (в нормальных СУБД) для этого используют вложенные запросы, когда результаты одного запроса передают другому запросу...
>Я слышал легенду о неких "временных" таблицах ;)
Есть такой зверь :), что самое приятное, при создании таблиц вложенные запросы в MySQL работают. В следующем примере я не совсем честно обращаюсь с базой данных, но это должно работать:
<?php
$query = "CREATE TEMPORARY TABLE ttt SELECT id_author, time, ip FROM ips ORDER BY id_author,time DESC";
$sel = "SELECT id_author, time, ip FROM ttt GROUP BY id_author";
mysql_query($query);
$res = mysql_query($sel);
if($res)
{
while($result = mysql_fetch_array($res))
{
echo $result["id_author"]." ".$result["time"]." ".$result["ip"]."<br>";
}
}
?>
|
По заврешению php-скрипта или вызова функции mysql_close() таблица ttt будет уничтожена. | |
|
|
|
|
|
|
|
для: Kirill
(03.09.2004 в 18:25)
| | То есть будет сводная таблица со всеми пользователями и их последними IP. Или для каждого в отдельности.
Ведь для одного пользователя сосчитать это легко. А для всех сразу... элегантно не получается.
А вот такой вариант: А может быть в базе сразу хранить только последний IP? При занесении IP посетителя в базу все оставшиеся удалять, а новый заносить. Вернее это будет один запрос - на обновление данных. | |
|
|
|
|
|
|
|
для: glsv (Дизайнер)
(03.09.2004 в 23:27)
| | > А вот такой вариант: А может быть в базе сразу хранить только >последний IP? При занесении IP посетителя в базу все >оставшиеся удалять, а новый заносить. Вернее это будет один >запрос - на обновление данных.
Так сделать нельзя, т.к. должен быть список всех IP пользователя =).
Т.е. изначально таблица, где показаны последние IP адреса пользователей, а также имеется возможность перехода к другой таблице, содержащей все IP адреса пользователя. | |
|
|
|
|
|
|
|
для: Kirill
(03.09.2004 в 11:09)
| | Еще 1 задачка ;)
Возможно ли, на базе вашего форума (используя ту базу, что он имеет) подсчитать минимальное, среднее, максимальное среднее время которое прошло до первого ответа в теме? Или надо какую-нибудь таблицу добавить? | |
|
|
|
|
|
|
|
для: Kirill
(06.09.2004 в 20:26)
| | Не очень понятно вот что: это для одной темы или для всех тем форума?
PS Примерчик бы конкретный здесь очень бы помог, а то мы сейчас каждый о своём будем думать :))) (3 темы в них по 6 сообщений, нужно получить то-то...) | |
|
|
|
|
|
|
|
для: cheops
(07.09.2004 в 11:09)
| | Есть форум (для того чтобы говорить на 1ом языке и решать 1 задачу. берем за основу БД для форума описанную в книге) .. в нем есть темы, в темах есть посты.
Так вот... необходимо найти средний, максимальный, минимальный промежуток времени между 1ым и вторым постом(если второй пост оставлен темже человеком, что и первый, то см третий etc) для всего форма (всех тем). Своеобразная скорость реакции (ответа) на вопрос. | |
|
|
|
|
|
|
|
для: Kirill
(07.09.2004 в 14:10)
| | Постараюсь ближе к полуночи сегодня более обстоятельно ответить... Здесь придётся тоже использовать временную таблицу с временами ответов посетителя, а потом проводить объединение её саму с собой, разница столбцов этого объединения даст нужный массив, в котором можно искать максимальное, минимальное и среднее... Работать, как и любое объединение это будет долго.
PS Кстати, при таком подходе получается ценным только минимальное время, так как максимальное будет равно разницы между первым сообщенем человека в форуме и последним, или имеются ввиду разница в рамках одной темы? В последнем случае жить было бы легче, так как в теме обычно не много сообщений, тем более одного и того же автора. | |
|
|
|
|
|
|
|
для: cheops
(07.09.2004 в 15:28)
| | имеется ввиду разница между первым сообщением 1го автора и первым ответом на него любого дургого.
Причем ответом мы считаем любое сообщение в теме от другого автора.
Т.е. допустим
1.30 - Петя: hi
1.45 - Саша: hello
1.55 - ...
нас интересует промежуток между 1.30 и 1.45 все остальное мы опускаем
И так в каждой теме. А статистика общая для всего форума. т.е. выясняем промежутки во всех темах и дальше находим минимальный, максимальный и средний. | |
|
|
|
|
|
|
|
для: Kirill
(07.09.2004 в 15:59)
| | А... Т.е. авторы разные... Всё равно в один запрос не получится :( И даже помоему не получится обойтись без рекурсивного спуска в PHP, так как MySQL не поддерживает внешних ключей (в версии 4). Нужно будет разворачивать каждую тему вычисляя время между предыдущим и последующим сообщением и помещать их в массив... Мда... вся эта конструкция будет долго работать :))) Если захотите это применить на практике, следует сразу вычислять временную разницу, при добавлении сообщения и помещать в базу данных, чтобы разнести нагрузку во времени... | |
|
|
|
|
|
|
|
для: cheops
(07.09.2004 в 16:45)
| | Обидно, но чтож.. веб программирование немного отличается от привычного :) | |
|
|
|
|
|
|
|
для: Kirill
(07.09.2004 в 16:58)
| | Да, я тоже долго привыкал :))), что программой могут одновременно по 100 человек пользоваться, а сама программа выполняется чёрт знает где и совсем не так как на локальной машине :))) | |
|
|
|
|
|
|
|
для: cheops
(07.09.2004 в 17:30)
| | Я вот провернул такую схему у меня все работает:
$rez=mysql_query( "SELECT id_author, ip, MAX(time_last) AS [mx_tm] FROM ips GROUP BY id_author, ip");
$tmp_auth=0;
$auth=0;
while($row=mysql_assoc_fetch($rez)){
$auth=$row["id_author"];
$mx_tm=$row["mx_tm"];
$ip=$row["ip"];
if($auth!=$tmp_auth){print "Time=".$mx_tm."IP=".$ip;}
$tmp_auth=$auth;
}
Результат запроса возвращает все строки но они отсортированы по убыванию максимального времени, поэтому каждая первая строка с новым ид автора это и есть время последнего посещения. Enjoy :-) | |
|
|
|
|
|
|
|
для: XPraptor
(07.09.2004 в 18:23)
| | Здесь IP-адрес не соответствует MAX(time_last) - я тоже сначала так хотел... :) Т.е. время-то максимальное, а IP-адрес первый попавшийся...
PS К тому же в этой ветке вторая проблема, надо было бы пост повыше запостить.... | |
|
|
|
|
|
|
|
для: cheops
(07.09.2004 в 18:52)
| | Не знаю почему у тебя IP первый попавшийся, у меня все в порядке с ним, он именно от этой строки с последним временем посещения, так как группировка именно по этим двум полям. | |
|
|
|
|
|
|
|
для: XPraptor
(08.09.2004 в 11:38)
| | Я использовал вот эту базу - получил бардак для первого пользователя. Если не сложно пришлите свой дамп. | |
|
|
|
|
|
|
|
для: cheops
(08.09.2004 в 12:32)
| |
[в базе]
217.21.51.1 1 07.09.2004
168.255.23.23 1 08.09.2004
123.142.23.25 1 09.09.2004
122.122.122.1 1 10.09.2004
241.232.232.1 2 07.09.2004
217.11.11.2 2 08.09.2004
222.11.22.11 3 07.09.2004
147.252.232.11 3 08.09.2004
165.236.215.32 3 09.09.2004
123.12.241.2 3 10.09.2004
123.245.123.1 4 07.09.2004
253.23.123.12 4 08.09.2004
[в запросе]
122.122.122.1 1 10.09.2004
123.142.23.25 1 09.09.2004
168.255.23.23 1 08.09.2004
217.21.51.1 1 07.09.2004
217.11.11.2 2 08.09.2004
241.232.232.1 2 07.09.2004
123.12.241.2 3 10.09.2004
147.252.232.11 3 08.09.2004
165.236.215.32 3 09.09.2004
222.11.22.11 3 07.09.2004
253.23.123.12 4 08.09.2004
123.245.123.1 4 07.09.2004
|
| |
|
|
|
|
|
|
|
для: XPraptor
(08.09.2004 в 14:03)
| | Хм... хотя я наверное понял почему так... у меня в силу причин сейчас MySQL 3.23 стоит - наверное он так на запрос реагирует :))) | |
|
|
|
|
|
|
|
для: Kirill
(06.09.2004 в 20:26)
| | К примеру вот так. Жаль одним запросом не получается :(
<?
// выбираем авторов тем, чтобы затем исключить их из следующего запроса
$query1="Select id_theme, id_author, author from posts where parent_post=0 group by id_theme";
$res = mysql_query($query1);
if($res)
{
while($result = mysql_fetch_array($res))
{
// запрашиваем темы, минимальное время ответа. Автор поста не должен быть равен автору темы.
$query2="Select id_theme, min(time) as min_time from posts where id_author<>".$result['id_author']." and id_theme=".$result['id_theme']." group by id_theme";
$resposts = mysql_query($query2);
if($resposts)
{
while($result2 = mysql_fetch_array($resposts))
{
echo $result2["id_theme"]." | ";
echo $result2["min_time"]."<br>";
}
}
}
}
?>
|
| |
|
|
|