#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