Одним запросом

monk

Новичок
Одним запросом

Помогите плз. Есть БД чата в ней более 30 тыс пользователей. Нужно подсчитать сколько человек в онлайн и вывести кто в какой комнате находится.
К примеру в БД записывается login и room

login |room
--------------
vasya | 1
--------------
petya | 2
--------------
sveta | 1
--------------
tolya | 3
--------------
nina | 4
-------------
gosha | 2
-------------
dima | 1

Нужно получить на выводе:
всего (7)
1: vasya, sveta,dima
2: petya, gosha
3: tolya
4: nina

Как можно сделать это одним запросом??
 

Wade2

Новичок
Я думаю, что одним запросом это сделать нельзя... ну т.е. теоретически можно, засунув всю таблицу в массив и обработав средствами PHP, но производительность будет уже не та, не та...

А с другой стороны - почему бы вам это не сделать?

SELECT login,room FROM table_name

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

monk

Новичок
Я думаю будет быстрее обрабатываться, ведб в бд более 30 тыс записей, лучше одним запросом а далее обрабатывать, но как сделать это:
1: vasya, sveta,dima
2: petya, gosha
3: tolya
4: nina
?
 

Wade2

Новичок
Запустить итерацию по всему результату.

И всех складывать в $array[counter][room]=name

а потом сделать вывод для каждой из комнат.
 

monk

Новичок
Спасибо, а можно пожалуйста более подробно описать систему...
 

Wade2

Новичок
Что-то вроде

PHP:
$result=mysql_query("SELECT login,room FROM table_name");
while($row=mysql_fetch_array($result))
{
$counter++;
$room=$row[room];
$login=$row[login];
$array[$counter][$room]=$login;

}
Пока писал - понял всю нетривиальность задачи :) Не получается навскидку дальше.

Возможно логика такая: потом схлопнуть через array_unique, сделать массив уникальных значений комнат. И для каждого значения делать поиск в общем массиве и тут же организовывать вывод.
 

WP

^_^
Я плакал и бился головой о стену (C) Даня Шеповалов.
PHP:
$result = mysql_query('SELECT * FROM table_name ORDER BY `room`');
$rooms = array();
while ($row = mysql_fetch_array($result))
{
 if (!isset($rooms[$row['room']])) {$rooms[$row['room']] = array();}
 $rooms[$row['room']][] = $row['login'];
}
for ($i = 0,$s = sizeof($rooms); $i < $s; $i++)
{
 echo ($i+1).': '.implode($rooms[$i]);
}
Код пишется с закрытыми глазами...
> есть БД чата в ней более 30 тыс пользователей.
Не увидел я в списке полей БД (заметь, ты структуру не дал) поля отвечающего за онлайновость.
 

monk

Новичок
немогу понять а что делает строка $array[$counter][$room]=$login;
?

-~{}~ 17.01.07 01:21:

WP
спасибо, буду смотреть код, а про то что онлай не дал, онлине лишнее. просто добывится в запрос условие...

-~{}~ 17.01.07 01:41:

ясно вроде, но у меня комнаты записаны не как 1,2,3,4 (это я тут как пример привел), а room1, room2, room3 и т.д. В этом случае тогда как быть?
 

Wade2

Новичок
Код пишется с закрытыми глазами...
WP, я такой и с открытыми буду писать минут 25. Потому что откровенно не люблю многомерные массивы.

Я плакал и бился головой о стену
Вы находите, что мой фрагмент вообще не будет работать? Будет ведь, просто криво. А мысль ведь была верная, просто я ее неважно развил.

-~{}~ 17.01.07 01:50:

WP, респект за код. изящное решение через implode. Ты открыл для меня пару новых возможностей в php :)
 

HraKK

Мудак
Команда форума
Сорри за оффтоп!
Wade2
$room=$row[room]; КАВЫЧКИ!
+ табиляции!
 

.des.

Поставил пиво кому надо ;-)
MySQL version >= 4.1

PHP:
$r = mysql_query("SELECT room, GROUP_CONCAT(login SEPARATOR ', ') AS logins FROM table_name GROUP BY room") or exit(mysql_error());
while ($row = mysql_fetch_array($r)) { 
  echo $row['logins']."<br/>";
}
 
Автор оригинала: Wade2
производительность будет уже не та, не та
Какая имхо нафик производительность когда чат на БД с 30тыс. записей и бегать по ней каждые напр. 10 сек. * 1000 юзеров = 0, потому-что БД не для чатов.

Извините, это мое личное мнение и просто удержаться не смог.
 

monk

Новичок
ура, кажется я сделал то что хотел благодарю WP!! Класс!
 

WP

^_^
Curly-fingers
Кури индексы + кеширование запросов. Фулскан не нужен.
 

monk

Новичок
"Кури индексы"

что делать?

-~{}~ 17.01.07 03:02:

WP
Еще раз спасибо, у меня все получилось так как нужно. Онромное спасибо!

-~{}~ 17.01.07 03:04:

Раньше выполнялось до 30 сек. а сейчас не более секунды точно. Приходится оптимизировать,а то долго обрабатываются скрипты да и хостер жалуется мол сервер грузит
 

WP

^_^
monk
Просто товарищ курли-фигингерс предположил надо будет бегать каждый раз по всей таблице, а я опроверг его предположение.
 

dron4ik

Новичок
можно немного облегчить
если поле онлайновости = "online"
и значение офлайн пользователя = "0"
То можно избавиться от флускана
SELECT * FROM table_name where `online`!=='0' ORDER BY `room`
 
WP
Курено - перекурено, но все-равно чат на БД - имхо это изврат.
Если речь идет о 30тыс. юзеров из которых, пусть 0.5% (примерно 150 юзеров), висят в онлайне, то о какой БД речь?
 
Сверху