Деревья в MySQL

RomanK

Новичок
Деревья в MySQL

Здравствуйте.

Незнаю как назвать тему :). Назвал как назвал. :)

Имеется две таблицы MySQL:

Код:
CREATE TABLE subjects
(
	`id` INT(11) unsigned NOT NULL auto_increment,
	`pid` INT(11) unsigned NOT NULL DEFAULT 0
);
Код:
CREATE TABLE messages
(
	`id` INT(11) unsigned NOT NULL auto_increment,
	`pid` INT(11) unsigned NOT NULL DEFAULT 0
);
pid в таблице messages - это id в таблице subjects. То есть для каждой строки в таблице subjects есть несколько строк в таблице messages.
Вот такой вот вопрос:
Пусть pid для таблицы subjects равен например 1.
Как одним запросом узнать количество строк в таблице subjects, удовлетворяющих условию pid=1, и количество строк в сумме в таблице messages, удовлетворяющих условию pid (для messages)=id (для subjects).
То есть: Как узнать, сколько тем с pid=1, и сколько сообщений в сумме удовлетворяет каждой теме с pid=1.

Блин, думаю понятно объяснил. :) Ну то есть простое дерево. :)

С уважением.
 

alpine

Новичок
Примерно так:
[sql]
SELECT COUNT(DISTINCT s.id) count_subjects, COUNT(m.id) as count_messages FROM subjects as s LEFT JOIN messages as m ON (s.id=m.pid) WHERE s.pid=1
[/sql]
 

Popoff

popoff.donetsk.ua
что-то типа этого:
select subjects.id,count(messages.*) from subjects,messages where subjects.pid=1 and messages.pid=subjects.id group by subjects.id

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

RomanK

Новичок
alpine
ОГРОМНОЕ ТЕБЕ ЧЕЛОВЕЧЕСКОЕ СПАСИБО. С меня пиво. :)

Popoff
Твой вариант не пробовал, но обязательно попробую. Тебе тоже пиво. :)
 

RomanK

Новичок
alpine
Если ты про чувака, то я не знал, что это кастрированый бык. Подправил. :)
 

RomanK

Новичок
Тут в связи с первым постом еще один вопрос.
Пусть в каждой таблице добавится еще одно поле: time.
Дак вот мне надо вытащить ID либо последней темы, либо, если есть, последнее сообщение для этой темы, ориентируясь по полю time. Но если в теме нет ни одного сообщения, то пусть ID последнего сообщения будет пустым.

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

Я просто написал форум, но у него за один раз по 60-90 запросов к БД. Дак вот в данный момент занимаюсь оптимизацией.

Спасибо всем, кто ответит. :)
 

RomanK

Новичок
alpine
Ой блин. Я не знаю. У меня все одним пакетом. (Денвер). Ну вложенные запросы я уже делал, если Вы о них хотели у меня спросить.
 

alpine

Новичок
RomanK
1) Завести поля в которые записывать id последнего поста, дату, автора тоесть все что тебе нужно для топика аналогично для форума.
2) Использовать подзапрос.

-~{}~ 04.01.06 12:50:

Кстати можно еще завести колонку в таблице subjects count_messages и для каждого нового поста count_messages=count_messages+1.
 

RomanK

Новичок
alpine
Я сейчас спрашиваю не конкретно для какого-либо форума, а именно по тому, что я написал. Т.е. есть две таблицы и надо по полю time вытащить последнее ID либо темы, либо (если есть) сообщения.
С помощью там всяких вложенных запросов или еще чего нибудь, можно ли такое сотворить одним запросом?
Спасибо.
 

alpine

Новичок
RomanK
У меня сложилось такое впечатление что ты думать самостоятельно не собираешься и пришел за готовым запросом, от меня ты его не получишь.

-~{}~ 04.01.06 13:19:

PS Если переписать это одним запросом глубоко сомневаюсь что повысится скорость. Мой совет пересмотреть структуру либо оставитьк как есть.
 

RomanK

Новичок
alpine
Не то у тебя впечатление.
Вчера до 4 часов ночи я об этом думал.
Сколько же я запросов перебрал.
Например:
[sql]SELECT FROM subjects AS s, messages AS m WHERE s.pid=1 AND m.create_time=(SELECT MAX(create_time) FROM messages WHERE m.pid=s.id);[/sql]
Но всегда что-то одно не получается.
Например если в теме нет сообщений, то вообще ничего не выведтся.
При другом запросе (что-нить изменю) наоборот, если сообщения есть, выведет время темы.
Еще пробовал: И тему правильно выводит, и сообщение выводит, но сообщение не последнее, а первое.

Дак вот подумал обратьится сюда за помощью.

P.S Очень редко обращаюсь за помощью на форум.

-~{}~ 04.01.06 14:25:

Автор оригинала: alpine
PS Если переписать это одним запросом глубоко сомневаюсь что повысится скорость. Мой совет пересмотреть структуру либо оставитьк как есть.
Просто согласитесь, 60-90 запросов, тоже не дело при большом количестве посетителей.
 

RomanK

Новичок
ПРОДОЛЖАЮ СОЗДАННУЮ КОГДА-ТО МНОЙ ТЕМУ

Немного усложним задачу.
Есть четыре таблицы: категории, форумы, топики, сообщения.
Нужно достать: все категории, все форумы для каждой категории, количество топиков в форуме, количество сообщений в топике, последний топик.

Сам запрос (кроме последнего топика я составил). Вот он:
[SQL]SELECT
s.id,
f.id,
COUNT(DISTINCT t.id),
COUNT(DISTINCT m.id)
FROM
sections AS s LEFT JOIN forums AS f ON (s.id=f.id_section)
LEFT JOIN topics AS t ON (f.id=t.id_forum)
LEFT JOIN messages AS m ON (t.id=m.id_topic)
GROUP BY f.id
ORDER BY s.id ASC, f.id ASC;[/SQL]

Пробовал вот так:
[SQL]SELECT
s.id,
f.id,
COUNT(DISTINCT t.id),
COUNT(DISTINCT m.id),
l.*
FROM
sections AS s LEFT JOIN forums AS f ON (s.id=f.id_section)
LEFT JOIN topics AS t ON (f.id=t.id_forum)
LEFT JOIN messages AS m ON (t.id=m.id_topic),
(SELECT * FROM topics WHERE `id_forum`=f.id ORDER BY `id` DESC LIMIT 1 ) AS l
GROUP BY f.id
ORDER BY s.id ASC, f.id ASC;[/SQL]
Но выводится ошибка - типа нет такой таблицы f.id. Я решил, что в подзапросе не действуют синонимы таблиц из главного запроса.

Дак вот вопрос: Как мне достать последний топик в форуме? Заранее спасибо. :)

-~{}~ 31.03.06 20:42:

Просто поднимаю тему в надежде на то, что кто-нибудь все таки мне поможет. :)
 
Сверху