Этот сайт не наркоманов. Это сайт программистов.

Добро пожаловать на Пыху!

Логин:
Пароль:
 

Нет прописки? Зарегистрируйся!

Новости

Пыха информатор 3.1
Еще более удобное оповещение о флуде!

Краснодарское время: 25 Май, 2012, 11:54:36

Страниц: [1] 2
Печать
Автор Тема: GROUP BY  (Прочитано 304 раз)
0 Пользователей и 1 Гость смотрят эту тему.
SpartakuS    ↓ 
21 Январь, 2012, 12:20:59
НЕ ХУЕТА! ХУЕТА!

Группа: Адекваты

Карма: 32
Сообщений: 2444
Сила слова: 1.31

В общем делаю личку типа как вконтакте. Для простоты есть табличка pm и поля id, time, sender, recipient.
Сначала написал нечто сложное, нифнига у меня не работало. Для теста сократил до короткого.
SQL
SELECT *
FROM  `pm`
WHERE sender = 1
GROUP BY sender
ORDER BY `time` DESC
LIMIT 0 , 30
Проблема в том, что групируется он получая первое добавленное сообщение, а мне надо последнее, как в ордере. Я понимаю, что это логично, но вот как выйти из ситуации что то не знаю.
Записан


цска ебаное гавно.
master    ↓ 
21 Январь, 2012, 12:35:22 , спустя 14 минут 23 секунды
НЕ ХУЕТА! ХУЕТА!

Квадратов сколько видишь ты?
Группа: Джедаи

Карма: 44
Сообщений: 2080
Сила слова: 2.12

*** тут был неправильный совет ***
 
зы.
если делать "where sender = 1 group by sender" то результатом получишь одну строку
 
зы2.
"select * group by ..." делать неправильно, потому что суть группировки - в применении к полям агрегатных функций. пример:
select sex, min(age) as min_age from people group by sex
Спустя 1 минуту 6 секунд добавил
дай полный запрос
Записан

SpartakuS    ↓ 
21 Январь, 2012, 12:43:30 , спустя 8 минут 8 секунд
НЕ ХУЕТА! ХУЕТА!

Группа: Адекваты

Карма: 32
Сообщений: 2444
Сила слова: 1.31

master, да выкинул я полный.
Про селект * груп  и агрегатные функции я знаю. Щас поясню что не нужно.
Из всех этих сообщений можно составить диалоги (это там где пара отправитель-получатель постоянная то есть все сообщения где я пишу васе или вася мне).
И получить все диалоги и последнее сообщение. Уже постепенно склоняюсь к выделению отдельной таблички под диалог. Тогда можно будет  бесболезненно расширить до групповых чатов, если понадобится.
Записан


цска ебаное гавно.
phpdude    ↓ 
21 Январь, 2012, 03:48:42 , спустя 3 часа 5 минут 12 секунд
НЕ ХУЕТА! ХУЕТА!

я - ЭМО
Группа: в ухо

Карма: 345
Сообщений: д-о-х-у-я!
Сила слова: 1.66

SQL

SELECT *, max(id) `last_message`
FROM  `pm`
WHERE sender = 1
GROUP BY sender
ORDER BY `time` DESC
LIMIT 0 , 30
 
както так, но ты один хуй получишь только его ID. это можно потом сжойнить с самой собой и получить message text или чо там тебе надо =)
Записан

забанен. могу забанить других, пишите в личку
BEER. Helping ugly people have sex since 1862.
Ivan    ↓ 
21 Январь, 2012, 07:16:18 , спустя 3 часа 27 минут 36 секунд
НЕ ХУЕТА! ХУЕТА!

Группа: Адекваты

Карма: 27
Сообщений: 1366
Сила слова: 1.98

Вот отрывок из моего быдлокода по похожей задаче:
PHP
public function getNewMessages($user_id) {
        $sql = "select count(*) from messages where message_to='$user_id' and message_status='0'";
        return $this->db->query($sql)->fetch_row();
    }

PHP
public function listMessages($user_id, $start = 0, $total = 10) {
        $sql = "select m.message_id as msgid, m.message_text as text,
        m.message_status as msgstatus, u.user_id as fromid, m.message_time as msgtime,
        u.user_name as fromname, u.user_surname as fromsurname
        from messages m
        join users u
        on m.message_from = u.user_id
        where m.message_to='$user_id'
        order by m.message_time desc
        limit $start, $total"
;
        return $this->db->query($sql)->full_assoc();
    }
Спустя 2 минуты 3 секунды добавил
PHP
public function removeMessages(array $ids, $owner_id) {
        $delstr  = (count($ids) > 1) ? 'in ('.join(',', $ids).')' : "='{$ids[0]}'";
        $this->db->delete("messages", "message_id $delstr and message_to='$owner_id'");
    }

Из всех этих сообщений можно составить диалоги
Сначала написал потом прочитал. Если такая фича есть то лучше действительно отдельную таблицу заведи!
Записан

SpartakuS    ↓ 
21 Январь, 2012, 07:56:10 , спустя 39 минут 52 секунды
НЕ ХУЕТА! ХУЕТА!

Группа: Адекваты

Карма: 32
Сообщений: 2444
Сила слова: 1.31

Ivan, Ты когда запросы пишешь - хоть капс то юзай, а то адЪ какой то)
Записан


цска ебаное гавно.
master    ↓ 
21 Январь, 2012, 09:43:20 , спустя 1 час 47 минут 10 секунд
НЕ ХУЕТА! ХУЕТА!

Квадратов сколько видишь ты?
Группа: Джедаи

Карма: 44
Сообщений: 2080
Сила слова: 2.12

SELECT *, max(id)
такой микс позволяет делать только mysql, другие субд не примут (и правильно). в результате такого запроса можешь получить непредсказуемую кашу.
пример
 
id name  age
1  vasya 22
2  vasya 33
3  sveta  44
 
делаем
select *, max(id) from people group by name where name='vasya'
в результате можем получить такое
id name  age
2  vasya 22
3  sveta  44
 
потому что столбцы агрегируются независимо. id был взят максимальный, а остальные столбцы - хер пойми как
Записан

AlexB    ↓ 
21 Январь, 2012, 12:34:20 , спустя 2 часа 51 минуту
НЕ ХУЕТА! ХУЕТА!

Группа: в ухо

Карма: 89
Сообщений: 3428
Сила слова: 2.6

Вообще-то, есть такая функция GROUP_CONCAT, которая отсортирует как угодно и соберет все id для sender. После чего, можно выцепить из строки первый на стороне пхп или строковыми функциями (не помню, чего там есть для этого в мускуле, вот в постгресе все круто - тип поля массив и слайсы). Только она имеет ограничение на длинну результирующей строки, поэтому нефигово бы наложить временные ограничения на запрос (напр. за последний месяц). Это, в любом случае надо, иначе чем дольше будет работать сервис - тем тормознее будет запрос.
« Последнее редактирование: 21 Январь, 2012, 12:33:25 от AlexB » Записан

SpartakuS    ↓ 
23 Январь, 2012, 09:53:42 , спустя 1 день 21 час 19 минут 22 секунды
НЕ ХУЕТА! ХУЕТА!

Группа: Адекваты

Карма: 32
Сообщений: 2444
Сила слова: 1.31

Спасибо мужики. Первую часть поборол (вчера позавчера не до работы было)
PHP
SELECT *
FROM `pm` WHERE `time` IN
( SELECT MAX(`time`) as `lastpm` FROM `pm` WHERE `sender` = 1 GROUP BY `recipient`)
Сейчас попробую посоединить входящие и исходящие.
« Последнее редактирование: 23 Январь, 2012, 09:53:42 от SpartakuS » Записан


цска ебаное гавно.
SpartakuS    ↓ 
25 Январь, 2012, 12:33:22 , спустя 1 день 14 часов 39 минут 40 секунд
НЕ ХУЕТА! ХУЕТА!

Группа: Адекваты

Карма: 32
Сообщений: 2444
Сила слова: 1.31

SQL
SELECT *
FROM `pm` AS `pm1` WHERE `time` IN
( SELECT MAX(`time`) AS `lastpm` FROM `pm` WHERE `sender` = 1 GROUP BY `recipient` )
LIMIT 10
UNION
SELECT *
FROM `pm` AS `pm2`
WHERE `time` IN
( SELECT MAX(`time`) AS `lastpm` FROM `pm` WHERE `recipient` = 1 GROUP BY `sender` )
LIMIT 10
Вот такую штуку сделал. Работает - только возвращает, но и входящие и исходящие. Можно как нибудь убрать более позднее, если у двух разных отправитель/получатель лишь меняются местами?
« Последнее редактирование: 25 Январь, 2012, 12:33:22 от SpartakuS » Записан


цска ебаное гавно.
phpdude    ↓ 
25 Январь, 2012, 12:43:42 , спустя 10 минут 20 секунд
НЕ ХУЕТА! ХУЕТА!

я - ЭМО
Группа: в ухо

Карма: 345
Сообщений: д-о-х-у-я!
Сила слова: 1.66

MAX(`time`)
я бы на твоем месте по ID группировал, ведь он пк + врядли у большего ID будет меньший time :D
Записан

забанен. могу забанить других, пишите в личку
BEER. Helping ugly people have sex since 1862.
SpartakuS    ↓ 
25 Январь, 2012, 01:58:02 , спустя 1 час 14 минут 20 секунд
НЕ ХУЕТА! ХУЕТА!

Группа: Адекваты

Карма: 32
Сообщений: 2444
Сила слова: 1.31

phpdude, ой, да. В коде у меня он по айди сделан. Просто запрос чуть старый)
Спустя 1 минуту 7 секунд добавил
Но то, что дуд даже не предположил ничего по проблеммен, немного пугает :D
Записан


цска ебаное гавно.
SpartakuS    ↓ 
25 Январь, 2012, 02:12:30 , спустя 14 минут 28 секунд
НЕ ХУЕТА! ХУЕТА!

Группа: Адекваты

Карма: 32
Сообщений: 2444
Сила слова: 1.31

Может решение неправильное на ровне архитектуры?
Записан


цска ебаное гавно.
phpdude    ↓ 
25 Январь, 2012, 02:53:01 , спустя 40 минут 31 секунду
НЕ ХУЕТА! ХУЕТА!

я - ЭМО
Группа: в ухо

Карма: 345
Сообщений: д-о-х-у-я!
Сила слова: 1.66


Может решение неправильное на ровне архитектуры?
да. обнозначно.
 
должна быть таблица тредов и не иначе. а ты ее хочешь скомпилить из сырых данных на лету.
 
это плохо:
1. это трудно
2. когда будет 10 тыс сообщений ты уже усрешся в сервак память добовлять :-)
3. нерасширяемо (ширяемо, слово то какое :D)
Записан

забанен. могу забанить других, пишите в личку
BEER. Helping ugly people have sex since 1862.
SpartakuS    ↓ 
25 Январь, 2012, 12:07:08 , спустя 9 часов 14 минут 7 секунд
НЕ ХУЕТА! ХУЕТА!

Группа: Адекваты

Карма: 32
Сообщений: 2444
Сила слова: 1.31

phpdude, если бы я архитектуру не мог поменять - все уже 100500 раз сказали бы, что архитектура говно, а вот могу - и молчат как партизаны :D
Записан


цска ебаное гавно.
Страниц: [1] 2
Печать
 

Перейти в: