Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737 Форумы портала PHP.SU :: Аналог list() для mysql
SELECT f .*,(SELECT COUNT(*)FROM Forum f0 WHERE f0.forum_id = f.id AND f0.type ='post')AS posts,
(SELECT COUNT(DISTINCT(f0.topic_id))FROM Forum f0 WHERE f0.forum_id = f.id AND f0.type ='post')AS topics
FROM Forum f
WHERE f.type ='forum'//вот так работает сечас
// А хочется что-то типа этого:
SELECT f .*, LIST((SELECT COUNT(*),COUNT(DISTINCT(f0.topic_id))FROM Forum f0 WHERE f0.forum_id = f.id AND f0.type ='post'),'posts','topics')FROM Forum f WHERE f.type ='forum'
EuGen
Отправлено: 11 Февраля, 2013 - 11:48:23
Профессионал
Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007 Откуда: Berlin
Помог: 707 раз(а)
Задача решается странными методами. Почему бы не обойтись обыкновенным JOIN (таблицы самой на себя)? Сделать list() не выйдет хотя бы по той причине, что понятие массива как ряда скаляров не имеет смысла в рамках запроса, потому, если велика охота сделать через подзапрос - можно оформить его как отдельную таблицу, и, опять же, через JOIN сделать выбор нужных полей.
----- Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
Anguis
Отправлено: 11 Февраля, 2013 - 12:00:02
Частый гость
Покинул форум
Сообщений всего: 253
Дата рег-ции: Июнь 2012
Помог: 2 раз(а)
Я пробовал через join - не вышло
Подобный запрос во-первых, выбирает не все type='forum', во-вторых неверно считает, может неверно составлен?
Когда нормальный человек, уезжая из дома одевает на жену пояс верности, веб-дизайнер ставит на нее счетчик...
EuGen
Отправлено: 11 Февраля, 2013 - 12:42:26
Профессионал
Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007 Откуда: Berlin
Помог: 707 раз(а)
Я, однако, не могу об этом догадываться (хоть и отвечал в той теме) - поскольку тем и сообщений на конференции очень много. Вопрос о задаче все еще в силе.
----- Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
Anguis
Отправлено: 11 Февраля, 2013 - 12:43:44
Частый гость
Покинул форум
Сообщений всего: 253
Дата рег-ции: Июнь 2012
Поля с текстом опустил, ибо вывод слишком большой для копипаста в сообщение.
EuGen
Отправлено: 11 Февраля, 2013 - 12:52:16
Профессионал
Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007 Откуда: Berlin
Помог: 707 раз(а)
Тогда где же фигурируют топики(темы)? Подозреваю, что поле user_topic каким-то образом за них "отвечает", но однозначно сказать не могу. И каково назначение, например, последних двух полей? (Не очень ясна структура - по-видимому, есть только одна таблица)
Я, конечно, могу попытаться переписать Ваш запрос, однако же логичнее понять архитектуру (и, возможно, её изменить) - чтобы добиться хорошей производительности и стройности данных.
----- Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
Anguis
Отправлено: 11 Февраля, 2013 - 13:06:56
Частый гость
Покинул форум
Сообщений всего: 253
Дата рег-ции: Июнь 2012
Помог: 2 раз(а)
Да, верно. Есть одна таблица для всего форума. За форумы отвечают записи с type=forum, за посты type=post, топики создаются тем-же type=post, только в topic_id записывается id только что созданной записи. И все последующие записи постов с аналогичным topic_id считаются постами топика. Вот и получается что DISTINCT(topic_id) type=post - это количество топиков, а COUNT(*) type=post - количество всего постов.
EuGen
Отправлено: 11 Февраля, 2013 - 13:10:49
Профессионал
Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007 Откуда: Berlin
Помог: 707 раз(а)
Anguis пишет:
Вот и получается что DISTINCT(topic_id) type=post - это количество топиков, а COUNT(*) type=post - количество всего постов.
Получается, что "количество постов" учтет в себе одновременно и количество тем?
Структура, конечно, странная. Если уж есть нужда делать подобным образом - я бы завел отдельный тип для темы (все равно Вы пишете 'forum' или 'post' - в строковом виде - надеюсь, это ENUM а не VARCHAR какой-нибудь - так от еще одного типа 'topic' оно не обеднеет).
----- Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
Anguis
Отправлено: 11 Февраля, 2013 - 13:22:54
Частый гость
Покинул форум
Сообщений всего: 253
Дата рег-ции: Июнь 2012
Помог: 2 раз(а)
А смысл нового типа? Что он даст?
Цитата:
Получается, что "количество постов" учтет в себе одновременно и количество тем?
Верно. Но в этом я не вижу ни чего странного, ибо при создании темы, создается и первый пост. Т.е. первое сообщение топика, тоже является постом.
Что касается архитектуры, то я согласен что текущая не правильная. Я-бы воспользовался постгрескуэль, с его сопряженными таблицами. Где верховная таблица отвечает за форумы, а каждая новая подтаблица - есть топик с записями всех сообщений.
Но я вынужден оптимизировать уже созданную не мной структуру, поэтому вопросы миграции и переделывание архитектуры не рассматриваются. Слишком дофига запросов придется править в коде.
Задача - оптимизировать запрос с двойным позапросом. Если с ним ни чего сделать не получится, тогда пусть остается так как есть.
И еще такой вопрос. Как вы считаете, при каком количестве записей такая таблица начнет тормозить? Форум школьного сайта. Расширяется не очень быстро. Просто возможно поднять вопрос переделывания архитектуры, но мне за это ни кто не заплатит, если я не докажу необходимость данного шага. (да врятли вообще они пойдут на этот шаг)
EuGen
Отправлено: 11 Февраля, 2013 - 13:50:30
Профессионал
Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007 Откуда: Berlin
Помог: 707 раз(а)
Если это форум школьного сайта, то, думаю, бояться нечего.
Странность здесь как минимум в неудобности использования этой структуры уже в рамках текущего приложения. То, что какая-либо выборка не вписывается в структуру - первый признак того, что эту структуру нужно поменять.
Каким образом СУБД postgree относится к архитектуре - немного не уловил мысль. Если это про внешние ключи - то их можно сделать и в MySQL.
Ну и менять эту структуру из соображений производительности все же стоило бы - поскольку в данном случае два (или же три - не суть важно) JOIN по внешнему ключу неоспоримо более быстры, чем два DEPENDED SUBQUERY в запросе по таблице, содержащей все данные форума.
----- Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
Anguis
Отправлено: 11 Февраля, 2013 - 15:44:21
Частый гость
Покинул форум
Сообщений всего: 253
Дата рег-ции: Июнь 2012
Помог: 2 раз(а)
Цитата:
Если это форум школьного сайта, то, думаю, бояться нечего.
На том можно и порешить
Цитата:
Странность здесь как минимум в неудобности использования этой структуры уже в рамках текущего приложения. То, что какая-либо выборка не вписывается в структуру - первый признак того, что эту структуру нужно поменять.
(SELECT COUNT(*)FROM test.Forum f0 WHERE f0.forum_id = f.id AND f0.type ='post')AS posts,
(SELECT COUNT(DISTINCT(f0.topic_id))FROM test.Forum f0 WHERE f0.forum_id = f.id AND f0.type ='post')AS topics
FROM test.Forum f WHERE f.type ='forum'
не вписывается в структуру? Потому что в нем есть подзапросы? А для чего тогда нужны подзапросы, если пользоваться ими неприемлемо? Не делали бы такую возможность и соблазна не было бы
Цитата:
Ну и менять эту структуру из соображений производительности все же стоило бы - поскольку в данном случае два (или же три - не суть важно) JOIN по внешнему ключу неоспоримо более быстры, чем два DEPENDED SUBQUERY в запросе по таблице, содержащей все данные форума.
Например как поменять структуру? Может лучше правильно расставить индексы и баста?
Ведь по-сути то эти запросы используются только при отображени списка форумов, не очень часто
mysql>EXPLAINSELECT f.*,(SELECT COUNT(*)FROM test.Forum f0 WHERE f0.forum_id = f.id AND f0.type ='post')AS posts,(SELECT COUNT(DISTINCT( f0.topic_id ))FROM test.Forum f0 WHERE f0.forum_id = f.id AND f0.type ='post')AS topics FROM test.Forum f WHERE f.type ='forum';
Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007 Откуда: Berlin
Помог: 707 раз(а)
Если Вы видите DEPENDED SUBQUERY, USING TEMPORARY или тем более USING FILESORT - то это сигнал к тому, что запрос не вписывается в архитектуру. Дело здесь либо в индексах (но в случае с зависимым подзапросом это не решит проблему), либо в том, что сами данные хранятся не так ,как требуется приложению для работы.
Anguis пишет:
А для чего тогда нужны подзапросы, если пользоваться ими неприемлемо? Не делали бы такую возможность и соблазна не было бы
Прошу прощения за ответом вопрос на вопрос, но для чего тогда нужен goto в том же php? Ведь сделали же такую возможность. Подзапросы - вещь, безусловно, удобная, однако же очень редко они нужны непременно. Почти всегда без них можно обойтись. В Вашем случае, к тому же, можно их заменить на JOIN, пример - обратите внимание, что я проиндексировал Вашу таблицу.
upd. странный все же fiddle. Днем отображал null extra вместо filesort - сейчас же - нет. План же на локальном mysql работает корректно, используя ключ
----- Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
Anguis
Отправлено: 11 Февраля, 2013 - 17:48:14
Частый гость
Покинул форум
Сообщений всего: 253
Дата рег-ции: Июнь 2012
Помог: 2 раз(а)
EuGen пишет:
можно их заменить на JOIN, <a href='http://sqlfiddle.com/#!2/fc1ce/1'>пример</a> - обратите внимание, что я проиндексировал Вашу таблицу.
Не чего по ссылке нет, окромя интерфейса. Оба поля пустые (Добавление)
мне понравилось на каком-то mysql форуме - "не всегда оно будет работать так, как вам хочется"
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.