СУММА подсчетов в динамических таблицах в виде столбцов MYSQL

#mysql

#mysql

Вопрос:

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

 SELECT f.username, 
(SELECT COUNT(id) FROM sites s WHERE s.username = f.username) site_count,
(SELECT COUNT(id) FROM banners b WHERE b.username = f.username) banner_count,
(SELECT COUNT(id) FROM favorites fa WHERE fa.username = f.username) favorite_count,
(SELECT COUNT(id) FROM social_posts so WHERE so.username = f.username) social_count,
(SELECT COUNT(id) FROM stream_updates st WHERE st.username = f.username) stream_count
FROM members f
    WHERE f.username 
      IN (SELECT friend2 as username FROM list_friends WHERE friend1 = :user
      AND friend2 <> :user)
    OR f.username 
      IN (SELECT friend1 as username FROM list_friends  WHERE friend2 = :user
    AND friend1 <> :user) 
    OR f.username = :user
  

ПРИМЕР ВЫВОДА:

 | username | site_count | banner_count | favorite_count | social_count | stream_count |
 ---------- ------------ -------------- ---------------- -------------- -------------- 
|  user1   |     7      |       12     |        3       |       5      |     11       |
|  user2   |     2      |        1     |        12      |       1      |     0        |
|  user3   |     5      |        7     |        4       |       9      |     25       |
  

Чего я надеюсь достичь для результата, так это суммы каждой строки:

 | username | site_count | banner_count | favorite_count | social_count | stream_count |
 ---------- ------------ -------------- ---------------- -------------- -------------- 
|          |    14      |       20     |        19      |      15      |     36       |
  

Ответ №1:

просто добавьте сумму для подсчета?

 SELECT f.username, 
    SUM((SELECT COUNT(id) FROM sites s WHERE s.username = f.username)) site_count,
    SUM((SELECT COUNT(id) FROM banners b WHERE b.username = f.username)) banner_count,
    SUM((SELECT COUNT(id) FROM favorites fa WHERE fa.username = f.username)) favorite_count,
    SUM((SELECT COUNT(id) FROM social_posts so WHERE so.username = f.username)) social_count,
    SUM((SELECT COUNT(id) FROM stream_updates st WHERE st.username = f.username)) stream_count
FROM members f
WHERE f.username 
  IN (SELECT friend2 as username FROM list_friends WHERE friend1 = :user
  AND friend2 <> :user)
OR f.username 
  IN (SELECT friend1 as username FROM list_friends  WHERE friend2 = :user
AND friend1 <> :user) 
OR f.username = :user
  

если вам нужны подсчеты каждого пользователя, просто добавьте Group By f.username в конец

Комментарии:

1. К сожалению, просто обертывание их в SUM не сократит это, хотелось бы, чтобы это было так просто. Это займет сумму каждого подсчета для каждого пользователя, что бесполезно. Например, если счетчик возвращает 5 для user1, выполнение суммы 5 не изменит результат. Также group by не будет работать, так как f.username и username из инструкции IN не совпадают и не могут быть сгруппированы как таковые. Я пытался создать группу по f.username, также пробовал группировать по имени пользователя, все это не привело ни к каким изменениям.

2. хорошо, тогда .. может быть, простой способ сделать это — подсчитать их из sql. если вы используете php, просто посчитайте их в php

3. На самом деле это может быть правильным решением, но я надеюсь на решение на основе sql, поскольку мне все равно нужно установить соединение для данных, и все данные индексируются, поэтому я хотел бы сделать это в mysql, если это возможно. 🙂

Ответ №2:

Мое решение состояло в том, чтобы использовать определяемые пользователем переменные с помощью :=, чтобы переменная обновлялась с каждой суммой.

Для получения более подробной информации прочитайте: http://dev.mysql.com/doc/refman/5.7/en/user-variables.html

Конечный результат обновленного запроса выглядит следующим образом:

 SELECT f.username,
@sites := SUM((SELECT COUNT(*) FROM sites s WHERE s.username = f.username)) AS site_count,
@banner := SUM((SELECT COUNT(*) FROM banners b WHERE b.username = f.username)) AS banner_count,
@favs := SUM((SELECT COUNT(*) FROM favorites fa WHERE fa.username = f.username)) AS favorite_count,
@social := SUM((SELECT COUNT(*) FROM social_posts so WHERE so.username = f.username)) AS social_count,
@stream := SUM((SELECT COUNT(*) FROM stream_updates st WHERE st.username = f.username)) AS stream_count
  FROM members f
     WHERE f.username 
     IN (SELECT friend2 as username FROM list_friends WHERE friend1 = :user
     AND friend2 <> :user)
  OR f.username 
     IN (SELECT friend1 as username FROM list_friends  WHERE friend2 = :user
     AND friend1 <> :user) 
  OR f.username = :user