SQL-запрос для потоковых сообщений - PullRequest
0 голосов
/ 30 марта 2012

Мой сайт имеет функцию обмена сообщениями, где один пользователь может отправлять сообщения другому.Сообщения поддерживают многопоточность - родительское сообщение может иметь любое количество дочерних элементов, но только один уровень.

Таблица сообщений выглядит следующим образом:

Messages
 - Id (PK, Auto-increment int)
 - UserId (FK, Users.Id)
 - FromUserId (FK, Users.Id)
 - ParentMessageId (FK to Messages.Id)
 - MessageText (varchar 200)

Я хочу отображать сообщения настраница с каждым «родительским» сообщением, за которой следует свернутое представление дочерних сообщений.

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

Я хотел бы получать сообщения, подобные этому:

Parent1
 Child1
 Child2
 Child3
Parent2
 Child1
Parent3
 Child1
 Child2

Ответы [ 2 ]

3 голосов
/ 30 марта 2012

Попробуй это. Вы можете заменить range_ с помощью некоторой переменной, хранящейся на вашем интерфейсе для нумерации страниц.

select child.MessageText from
(select @i:=@i+1 as range_, id, MessageText from messages, (select @i:=0) k where ParentMessageId is null order by id asc) parent 
left outer join messages child on (parent.id = child.ParentMessageId or parent.id = child.id)
where parent.range_ between 1 and 3;
2 голосов
/ 30 марта 2012

Вы можете использовать временный идентификатор для заказа сообщений. Если сообщение является Parent, то временный идентификатор будет равен идентификатору, в противном случае временный идентификатор будет равен ParentMessageID. Тогда вам просто нужно заказать по временному ID

SELECT Messages.*, 
CASE WHEN ParentMessageId IS NULL THEN Id ELSE ParentMessageId END AS tempId 
FROM Messages
ORDER BY tempId

Редактировать

Если вам нужны первые 10 записей, вы можете сначала получить идентификаторы, а затем выполнить запрос

SELECT Messages.*, 
CASE WHEN ParentMessageId IS NULL THEN Id ELSE ParentMessageId END AS tempId 
FROM Messages
WHERE Messages.tempId IN (SELECT Messages.Id 
                      FROM Messages
                      WHERE ParentMessageId IS NULL
                      LIMIT 10
                      ORDER BY Messages.Id )
ORDER BY tempId

Таким образом, вы получаете сообщения и соответствующие дочерние элементы только из первых 10 сообщений.

...