За последние 24 часа нас посетили 18005 программистов и 1645 роботов. Сейчас ищут 1962 программиста ...

Подсчет комментов

Тема в разделе "MySQL", создана пользователем Nikolai_, 21 июн 2014.

  1. Nikolai_

    Nikolai_ Активный пользователь

    С нами с:
    27 авг 2010
    Сообщения:
    133
    Симпатии:
    0
    Проблема в следующем.

    Есть 2 таблицы:
    Код (Text):
    1. CREATE TABLE `archive` (
    2.   `id` int(6) AUTO_INCREMENT,
    3.   `name` varchar(256) DEFAULT NULL,
    4.   `text` longtext NOT NULL,
    5.   PRIMARY KEY (`id`)
    6. ) ENGINE=MyISAM;
    7.  
    8. CREATE TABLE `coms` (
    9.   `id` int(6) AUTO_INCREMENT, // ид коммента
    10.   `id_type` int(1) NOT NULL DEFAULT '0', // ид типа коммента (1 - к статье, 2 - к фото)
    11.   `id_` int(6) unsigned DEFAULT NULL, // ид статьи или фото
    12.   `text` text NOT NULL,
    13.   PRIMARY KEY (`id`)
    14. ) ENGINE=MyISAM;
    1-я таблица со статьями, а 2-я - с комментами к ней. В таблицу с coms помимо комментов к статьям, пишутся и комменты к фото в галерее. Для их различения при выводе (т.к. id фото и статьи может быть одинаковым) есть поле id_type, куда пишется 1 для статьи, 2 - для фото.

    Необходимо вывести заголовки статей и количество комментов к каждой статье.

    Ранее пока в таблице были лишь комменты к статьям и не было поля id_type подсчет был таким (при выводе заголовков статей):
    Код (Text):
    1. "SELECT a.*, IF(c.id IS NULL, 0, COUNT(*)) count_coms
    2.  FROM archive a LEFT JOIN coms c ON a.id=c.id_
    3.  GROUP BY a.id
    4.  ORDER BY a.date DESC;";
    Что в этом запросе подправить, чтобы решить озвученную выше задачу (выделенную жирным шрифтом).
     
  2. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.115
    Симпатии:
    1.244
    Адрес:
    там-сям
    между FROM и GROUP BY добавь WHERE где укажи свое условие.

    логическая ошибка писать * когда группируешь записи. во фразе SELECT должны быть только поля из списка GROUP BY + агрегатные функции от других полей. иначе не удивляйся странным результатам.

    а что это за магия с IF(c.id…) ? не знаю что ты хотел выразить, но достаточно написать COUNT(c.id), а в других контекстах пригодится функция IFNULL()
     
  3. Nikolai_

    Nikolai_ Активный пользователь

    С нами с:
    27 авг 2010
    Сообщения:
    133
    Симпатии:
    0
    Так не пойдет. В таком случае будут выводится статьи, к которым есть комменты. А надо выводить все, в т.ч. и без комментов.
     
  4. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.115
    Симпатии:
    1.244
    Адрес:
    там-сям
    дык! напиши условие, учитывая случай null. или то же условие помести в LEFT JOIN … ON …

    пытайся ёмана! дорогу осилит идущий.

    а, ладно, всё равно не справишся )))
    Код (PHP):
    1. SELECT 
    2.   a.`id`, /* ты можешь поставить a.* но это фигово -- гугли MYSQL ANSI MODE */
    3.   COUNT(c.`id`) AS `count_coms`
    4. FROM 
    5.   `archive` AS a LEFT JOIN 
    6.   `coms` AS c ON a.`id`=c.`id_` AND c.`id_type`=1
    7. GROUP BY a.`id`
    8. ORDER BY a.`id` DESC /* поле date отсутствует! */
    http://sqlfiddle.com/#!2/e87ea1/3

    Добавлено спустя 3 минуты 57 секунд:
    p.s.
    Намного мудрее было бы иметь поле со счетчиком комментариев в самой таблице статей. На форумах именно так сделано — тема содержит счетчик комментариев, раздел содржит счетчик тем, пользователь содержит счетчик сделанных постов и т.д. и т.п. Слишком накладно всякий раз суммировать. Проще изменять счетчик в транзакции добавления камента.

    Операции добавления случаются во много раз реже, чем чтения. Оптимизировать надо частые операции.
     
  5. Nikolai_

    Nikolai_ Активный пользователь

    С нами с:
    27 авг 2010
    Сообщения:
    133
    Симпатии:
    0
    Спасибо, artoodetoo! Теперь все как надо работает.

    На сайте сравнительно немного людей. Поэтому пока вполне можно обойтись без дополнительных полей и кода.