Как я могу посчитать количество записей в двух других таблицах с помощью MYSQL?

#mysql #sql #database

#mysql #sql #База данных

Вопрос:

У меня есть три таблицы.

  • Публикации
  • Изображения
  • Голосов

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

Этот код работает для получения оценки записи

 SELECT 
    posts.*, 
    COALESCE(SUM(votes.value), 0) as score
FROM posts 
    LEFT JOIN votes ON posts.post_id = votes.target_id
GROUP BY posts.post_id
  

и этот код работает для получения количества изображений вместе с сообщениями

 SELECT 
    posts.*, 
    COALESCE(COUNT(images.image_id), 0) as num_images
FROM posts 
    LEFT JOIN images ON posts.post_id = images.belongs_to_post
GROUP BY posts.post_id
  

но если я объединю эти две, чтобы получить

 SELECT 
    posts.*, 
    COALESCE(COUNT(images.image_id), 0) as num_images,
    COALESCE(SUM(votes.value), 0) as score
FROM posts 
    LEFT JOIN votes ON posts.post_id = votes.target_id
    LEFT JOIN images ON posts.post_id = images.belongs_to_post
GROUP BY posts.post_id
  

score умножается на количество изображений. Как я могу эффективно остановить это? Должен ли я группировать по другому столбцу?

Я использую MySQL 5.7.31.

Ответ №1:

Я бы рекомендовал коррелированные подзапросы:

 SELECT p.*, 
       (SELECT COUNT(*)
        FROM images i
        WHERE p.post_id = i.belongs_to_post
       ) as num_images,
       (SELECT COALESCE(SUM(v.value), 0)
        FROM votes v
        WHERE p.post_id = v.target_id
       ) as score
FROM posts p;
  

С индексами на images(belongs_to_post) и votes(target_id, value) это, вероятно, намного быстрее, чем любой подход, который использует агрегацию во внешнем запросе.