|
|
|
| Добрый день, поискала похожие темы, кое-что нашлось, но немного не то...
Есть 3 таблицы
forums - список форумов
id_f
name
threads - темы принадлежащие форумам
id_t
name
id_forum
messages - сообщения, принадлежащие определенной теме
id_m
name
id_theme
|
Нужно 1 запросом сделать выборку, чтобы получилось:
Список форумов | Кол-во тем в каждом форуме | Кол-во сообщений в каждом форуме
|
Делаю так:
SELECT f.name, cth FROM forums f
LEFT JOIN (SELECT COUNT(id_t) AS cth, id_f FROM threads GROUP BY id_f )
AS t_counts ON f.id_f = t_counts.id_f
|
Выводит только форумы и кол-во тем, как усовершенствовать запрос, чтобы выводил еще и кол-во сообщений? | |
|
|
|
|
|
|
|
для: selma
(16.11.2012 в 02:51)
| |
/*<?*/
SELECT f.name
, coalesce(count(*),0)theme_count
, coalesce(sum(co),0)message_count
FROM forums f
LEFT JOIN threads ON id_f=id_forum
LEFT JOIN( SELECT id_theme
, count(*)co
FROM messages
GROUP BY id_theme
)t ON id_theme=id_t
GROUP BY f.name,id_forum
| кажись так. Но чет я спросони не уверен =) | |
|
|
|
|
|
|
|
для: Sfinks
(16.11.2012 в 08:38)
| | theme_count считает не корректно | |
|
|
|
|
|
|
|
для: selma
(16.11.2012 в 08:54)
| | Форумы без тем есть? В них некорректность? Исправьте последнее GROUP BY на | |
|
|
|
|
|
|
|
для: Sfinks
(16.11.2012 в 08:56)
| | со скрипом, но работает:) спасибо
Я еще не проверяла, как будет отрабатывать запрос в случае отсутствия тем или сообщений в каком-либо из форумов. | |
|
|
|
|
|
|
|
для: selma
(16.11.2012 в 09:00)
| | "со скрипом" - Что бы это значило..... =( | |
|
|
|
|
|
|
|
для: Sfinks
(16.11.2012 в 09:02)
| | со скрипом, это долгое выполнение:) | |
|
|
|
|
|
|
|
для: selma
(16.11.2012 в 09:10)
| | Полностью.
Во первых изменится условие задачи.
Имя темы, когда весь форум схлопнут в 1 строчку, может быть только одно.
Значит оно должно выбираться по какому-то условию.
name какой именно темы?
- Первой/последней по времени создания?
- Той, в которой было последнее сообщение в пределах данного форума?
- Той, в которой больше всего сообщений?
- Той, в чаще всего встречается буква "я"?
- Той, где меньше матерятся?
Ну и т.п..... | |
|
|
|
|
|
|
|
для: Sfinks
(16.11.2012 в 09:23)
| |
- Той, в которой было последнее сообщение в пределах данного форума?
|
но я в приниципе сделала, добавила поле last_m в тблицу threads и еще один LEFT JOIN в запрос
SELECT f.*, lst, COALESCE(count(*),0) AS ct, COALESCE(sum(co),0) AS cm
FROM forums f
LEFT JOIN threads ON f.id_f=threads.id_f
LEFT JOIN( SELECT id_t, count(*) AS co
FROM messages
GROUP BY id_t ORDER BY id_m
)t ON threads.id_t=t.id_t
LEFT JOIN(
SELECT id_f, MAX( last_m ) AS lst
FROM threads
GROUP BY id_f
) AS t_counts ON f.id_f = t_counts.id_f
GROUP BY f.names,f.id_f
|
И вылез косячок, когда тем нет совсем ни в одном из форумов, показывает 1 причем в каждом форуме | |
|
|
|
|
|
|
|
для: selma
(16.11.2012 в 09:24)
| | Чет вы быстро сообщения редактируете. Вообще не понятно к чему я предыдущий пост написал. =) Наверно я подожду, может передумаете..... =))
> показывает 1 причем в каждом форуме
странно. Покажите дамп таблиц вместе с SHOW CREATE, чтоб я у себя мог попробовать. | |
|
|
|
|
|
|
|
для: Sfinks
(16.11.2012 в 09:30)
| |
CREATE TABLE IF NOT EXISTS `forums` (
`id_f` int(9) NOT NULL AUTO_INCREMENT,
`names` text NOT NULL,
PRIMARY KEY (`id_f`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
--
-- Дамп данных таблицы `forums`
--
INSERT INTO `forums` (`id_f`, `names`) VALUES
(1, 'Культура и развлечения'),
(2, 'Вопросы Администрации сайта');
CREATE TABLE IF NOT EXISTS `messages` (
`id_m` int(9) NOT NULL AUTO_INCREMENT,
`names` text NOT NULL,
`id_t` int(9) NOT NULL,
`times` varchar(10) NOT NULL,
PRIMARY KEY (`id_m`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `threads` (
`id_t` int(9) NOT NULL AUTO_INCREMENT,
`names` text NOT NULL,
`id_f` int(9) NOT NULL,
`last_m` int(9) NOT NULL,
PRIMARY KEY (`id_t`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
|
| |
|
|
|
|
|
|
|
для: selma
(16.11.2012 в 09:46)
| | Да, все верно. Правильно так:
SELECT f.names
, count(th.id_f)theme_count
, coalesce(sum(co),0)message_count
FROM forums f
LEFT JOIN threads th ON f.id_f=th.id_f
LEFT JOIN( SELECT id_t
, count(*)co
FROM messages
GROUP BY id_t
)t ON th.id_t=t.id_t
GROUP BY f.names,f.id_f
|
Ускорить можно денормализацией.
Если в таблицу threads добавить поле mess_co, то можно избавиться от вложенного подзапроса t.
Для определения темы с последним сообщением лучше не last_m в threads, а сразу last_theme в forums.
times - тип DATETIME или TIMESTAMP лучше использовать. У MySQL довольно богатый набор функций для работы с данными типа дата-время. Не нужно лишать себя этого функционала. | |
|
|
|
|
|
|
|
для: Sfinks
(16.11.2012 в 10:13)
| | Спасибо работает. Структуру поправила, теперь вроде такой запрос:
SELECT f . * , coalesce( SUM( th.mess_co ) , 0 ) AS cm, count( th.id_f ) AS ct
FROM forums f
LEFT JOIN threads th ON f.id_f = th.id_f
GROUP BY f.names, f.id_f
|
верно?
Уважаемый Sfinks я не могу вас дозваться в icq, вы там бываете?
Есть несколько вопросов | |
|
|
|
|
|
|
|
для: selma
(16.11.2012 в 10:21)
| | Аська - зло :) Я там тоже по году не бываю
Чем вас форум не устраивает? У Сфинкса уже давно тут прописка :) | |
|
|
|
|
|
|
|
для: selma
(16.11.2012 в 10:21)
| | Верно.
Только у вас th.mess_co может быть null? Думаю нет. Т.е. для тем в которых нет сообщений оно равно 0. Значит coalesce() не нужно.
В аське тоже бываю раз в год по обещанию. Сейчас она у меня даже не установлена.
Лучше задавайте вопросы тут. | |
|
|
|
|
|
|
|
для: Sfinks
(16.11.2012 в 12:07)
| | По факту, я согласна с вами, аська - зло. Но я считаю, что здесь, на форуме, все черезчур уж обезличено. Надо все равно приват-контакт сделать. Вдруг человек захочет обратиться к кому-либо за "фриланс помощью"? | |
|
|
|
|
|
|
|
для: selma
(16.11.2012 в 12:18)
| | Для этого в каждом сообщении есть ссылка "письмо автору" | |
|
|
|
|
|
|
|
для: Sfinks
(16.11.2012 в 13:38)
| | Когда-то уже обсуждалось, что эта ссылка не работает:(
Но я попробую снова:) | |
|
|
|