ФорумРазработкаБазы данных → GROUP BY

GROUP BY

  • VaseninM

    Сообщения: 2416 Репутация: N Группа: Адекваты

    Spritz Янв. 21, 2012, 12:20 д.п.

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

    Проблема в том, что групируется он получая первое добавленное сообщение, а мне надо последнее, как в ордере. Я понимаю, что это логично, но вот как выйти из ситуации что то не знаю.
  • master

    Сообщения: 3244 Репутация: N Группа: Джедаи

    Spritz Янв. 21, 2012, 12:35 д.п., спустя 14 минут 23 секунды

    *** тут был неправильный совет ***

    зы.
    если делать "where sender = 1 group by sender" то результатом получишь одну строку

    зы2.
    "select * group by …" делать неправильно, потому что суть группировки - в применении к полям агрегатных функций. пример:
    select sex, min(age) as min_age from people group by sex
    Спустя 66 сек.
    дай полный запрос
    не всё полезно, что в swap полезло
  • VaseninM

    Сообщения: 2416 Репутация: N Группа: Адекваты

    Spritz Янв. 21, 2012, 12:43 д.п., спустя 8 минут 8 секунд

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

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz Янв. 21, 2012, 3:48 д.п., спустя 3 часа 5 минут 12 секунд


    SELECT *, max(id) `last_message`
    FROM `pm`
    WHERE sender = 1
    GROUP BY sender
    ORDER BY `time` DESC
    LIMIT 0 , 30

    както так, но ты один хуй получишь только его ID. это можно потом сжойнить с самой собой и получить message text или чо там тебе надо =)
    Сапожник без сапог
  • VaseninM

    Сообщения: 2416 Репутация: N Группа: Адекваты

    Spritz Янв. 21, 2012, 7:56 д.п., спустя 4 часа 7 минут 28 секунд

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

    Сообщения: 3244 Репутация: N Группа: Джедаи

    Spritz Янв. 21, 2012, 9:43 д.п., спустя 1 час 47 минут 10 секунд

    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 был взят максимальный, а остальные столбцы - хер пойми как
    не всё полезно, что в swap полезло
  • AlexB

    Сообщения: 4306 Репутация: N Группа: в ухо

    Spritz Янв. 21, 2012, 12:34 п.п., спустя 2 часа 51 минуту

    Вообще-то, есть такая функция GROUP_CONCAT, которая отсортирует как угодно и соберет все id для sender. После чего, можно выцепить из строки первый на стороне пхп или строковыми функциями (не помню, чего там есть для этого в мускуле, вот в постгресе все круто - тип поля массив и слайсы). Только она имеет ограничение на длинну результирующей строки, поэтому нефигово бы наложить временные ограничения на запрос (напр. за последний месяц). Это, в любом случае надо, иначе чем дольше будет работать сервис - тем тормознее будет запрос.
  • VaseninM

    Сообщения: 2416 Репутация: N Группа: Адекваты

    Spritz Янв. 23, 2012, 9:53 д.п., спустя 1 день 21 час 19 минут

    Спасибо мужики. Первую часть поборол (вчера позавчера не до работы было)
    SELECT *
    FROM `pm` WHERE `time` IN
    ( SELECT MAX(`time`) as `lastpm` FROM `pm` WHERE `sender` = 1 GROUP BY `recipient`)

    Сейчас попробую посоединить входящие и исходящие.
  • VaseninM

    Сообщения: 2416 Репутация: N Группа: Адекваты

    Spritz Янв. 25, 2012, 12:33 д.п., спустя 1 день 14 часов 39 минут

    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

    Вот такую штуку сделал. Работает - только возвращает, но и входящие и исходящие. Можно как нибудь убрать более позднее, если у двух разных отправитель/получатель лишь меняются местами?
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz Янв. 25, 2012, 12:43 д.п., спустя 10 минут 20 секунд

    MAX(`time`)

    я бы на твоем месте по ID группировал, ведь он пк + врядли у большего ID будет меньший time :D
    Сапожник без сапог
  • VaseninM

    Сообщения: 2416 Репутация: N Группа: Адекваты

    Spritz Янв. 25, 2012, 1:58 д.п., спустя 1 час 14 минут 20 секунд

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

    Сообщения: 2416 Репутация: N Группа: Адекваты

    Spritz Янв. 25, 2012, 2:12 д.п., спустя 14 минут 28 секунд

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

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz Янв. 25, 2012, 2:53 д.п., спустя 40 минут 31 секунду


    Может решение неправильное на ровне архитектуры?
    да. обнозначно.

    должна быть таблица тредов и не иначе. а ты ее хочешь скомпилить из сырых данных на лету.

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

    Сообщения: 2416 Репутация: N Группа: Адекваты

    Spritz Янв. 25, 2012, 12:07 п.п., спустя 9 часов 14 минут 7 секунд

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

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz Янв. 25, 2012, 12:44 п.п., спустя 37 минут 5 секунд

    SpartakuS, ну заведи треды :-)
    Спустя 13 сек.
    хуйктознает чо у тя там, может ваще герпис
    Сапожник без сапог

Пожалуйста, авторизуйтесь, чтобы написать комментарий!