Вопрос:

Мои темы-MySQL-запрос-счетчик не работает

mysql

26 просмотра

1 ответ

159 Репутация автора

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

Для этого примера у меня есть две таблицы:

 Table 1 : fo_forums
 ID | parent (id) | title

 Table 2 : fo_topics
 ID | parent (id) | title

У форума МОЖЕТ быть родитель (который также является форумом), и у этого родителя МОЖЕТ быть родитель (другой форум), но у последнего не может быть родителя. (Таким образом, мы можем просто иметь 3 поколения форумов)

У темы есть родитель, а это форум.

Я пытаюсь выполнить одну простую вещь: получить список форумов с количеством тем внутри них и внутри их потенциальных детей (от 0 до 2 детей) .

Я проверил много вещей, последнее, что я сделал:

SELECT fo.fo_id, 
 (SELECT COUNT(fot_id) FROM fo_topics
    WHERE fot.parent = fo.fo_id OR fot.parent = foc1.fo_id OR fot.parent = foc2.fo_id
 ) as count
FROM fo_forums as fo
 LEFT JOIN fo_forums as foc1 ON foc1.fo_parent = fo.fo_id
 LEFT JOIN fo_forums as foc2 ON foc2.fo_parent = foc1.fo_id

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

Пожалуйста, обратите внимание:

  • я использую MySQL
  • это упрощенный запрос (я получаю другие вещи о форуме в «реальном запросе», но с этим или без него ничего не меняется)

Спасибо за вашу помощь.

Автор: Vae Источник Размещён: 08.03.2017 11:53

Ответы (1)


0 плюса

159 Репутация автора

После нескольких часов работы (слишком много часов, tbh) лучшее, что я мог бы получить, это те 2 версии: (это на французском языке, плз, не беспокойтесь)

Version 1:
SELECT DISTINCT fo.fo_id, fo.fo_parent, fo.fo_type, fo.fo_statut, fo.fo_ordre, fo.fo_titre,
    COUNT(DISTINCT fot.fot_id) as nbr_topics, 
    COUNT(DISTINCT fot2.fot_id) as nbr_topics_enfants, 
    COUNT(DISTINCT fop.fop_id) as nbr_posts,
    COUNT(DISTINCT fop2.fop_id) as nbr_posts_enfants,
    fopi.fop_id, fopi.fop_timestamp, fopi.fop_fotid, fopi.fop_uid, u.u_pseudonyme, u.u_avatar, foti.fot_id, foti.fot_titre
FROM fo_forums as fo
    LEFT JOIN fo_forums as foe ON foe.fo_parent = fo.fo_id
    LEFT JOIN fo_forums as fope ON fope.fo_parent = foe.fo_id
    LEFT JOIN fo_topics as fot ON (fot.fot_foid = fo.fo_id)
        LEFT JOIN fo_posts as fop ON fop.fop_fotid = fot.fot_id
    LEFT JOIN fo_topics as fot2 ON (fot2.fot_foid = foe.fo_id OR fot2.fot_foid = fope.fo_id)
        LEFT JOIN  fo_posts as fop2 ON fop2.fop_fotid = fot2.fot_id
    LEFT JOIN fo_posts as fopi ON fopi.fop_id = (SELECT MAX(fot_derniermsg) FROM fo_topics WHERE (fot_foid = fo.fo_id))
        LEFT JOIN fo_topics as foti ON foti.fot_id = fopi.fop_fotid
        LEFT JOIN u_individus as u ON u.u_id = fopi.fop_uid
GROUP BY fo.fo_id

А также :

Version 2
SELECT DISTINCT fo.fo_id, fo.fo_parent, fo.fo_type, fo.fo_statut, fo.fo_ordre, fo.fo_titre,
    (SELECT COUNT(fot.fot_id) FROM fo_topics as fot WHERE fot.fot_foid = fo.fo_id) as nbr_topics,
    (SELECT COUNT( fot.fot_id) FROM fo_topics as fot 
        LEFT JOIN fo_forums as foe ON foe.fo_id IS NOT NULL 
        LEFT JOIN fo_forums as fope ON fope.fo_parent = foe.fo_id 
    WHERE ( (foe.fo_parent = fo.fo_id) AND (fot.fot_foid = foe.fo_id OR fot.fot_foid = fope.fo_id))
    ) as nbr_topics_enfants,
    (SELECT COUNT(fop.fop_id) FROM fo_posts as fop JOIN fo_topics as fot ON fot.fot_id = fop.fop_fotid WHERE fot.fot_foid = fo.fo_id) as nbr_posts,
    (SELECT COUNT( fop.fop_id) FROM fo_topics as fot 
        LEFT JOIN fo_forums as foe ON foe.fo_id IS NOT NULL 
        LEFT JOIN fo_forums as fope ON fope.fo_parent = foe.fo_id
        LEFT JOIN fo_posts as fop ON fop.fop_fotid = fot.fot_id
    WHERE ( (foe.fo_parent = fo.fo_id) AND (fot.fot_foid = foe.fo_id OR fot.fot_foid = fope.fo_id))
    ) as nbr_posts_enfants,
    fopi.fop_id, fopi.fop_timestamp, fopi.fop_fotid, fopi.fop_uid, u.u_pseudonyme, u.u_avatar, foti.fot_id, foti.fot_titre
FROM fo_forums as fo
    LEFT JOIN fo_posts as fopi ON fopi.fop_id = (SELECT MAX(fot_derniermsg) FROM fo_topics WHERE (fot_foid = fo.fo_id))
        LEFT JOIN fo_topics as foti ON foti.fot_id = fopi.fop_fotid
        LEFT JOIN u_individus as u ON u.u_id = fopi.fop_uid

С этим я могу получить:

  • все основные сведения о форуме (название, статус ...)
  • количество тем, напрямую связанных с форумом
  • количество тем, связанных с детьми форума (имеется в виду: другие форумы)
  • количество постов в темах форума
  • количество постов в темах форума детей
  • информация (идентификатор, дата и информация о пользователе) последнего сообщения / темы на форуме

Это немного грязно, по крайней мере, на мой взгляд, и я почти уверен, что есть более хороший способ и более эффективный способ сделать это, но я не могу понять, как это сделать.

Довольно удивительно, по крайней мере для меня, вторая версия быстрее, чем первая.

Если у кого-то есть идея улучшить это, я открыт для предложений. А пока это будет моя функция!

Автор: Vae Размещён: 09.03.2017 08:54
Вопросы из категории :
32x32