Арифметика Count() в mysql

#mysql

#mysql

Вопрос:

У меня есть две таблицы:

 comments (
  id        int
  comment   int
)

commentvotes (
  commentid int
  positive  bool
)
  

Где commentvotes.positive определяет, было ли голосование положительным или отрицательным.

Есть ли какой-либо способ, с помощью одного запроса, чтобы я мог получить все положительные и отрицательные отзывы, в идеале в столбце каждый? В более общем плане, можете ли вы выполнить два подсчета с разными критериями выбора в одном запросе?

Ответ №1:

Вы можете проделывать глупые трюки с SUM :

 SELECT commentid, SUM(positive) upvotes, SUM(NOT positive) downvotes FROM commentvotes;
  

Логические значения MySQL на самом деле являются просто целыми числами, 0 или 1. Их сложение эффективно подсчитывает, сколько раз условие выполняется. Итак, если у вас есть:

 commentid | positive
----------|---------
 1        |  true
 1        |  true
 1        |  false
 1        |  true
 1        |  false
  

Тогда SUM(positive) равно 1 1 0 1 0 = 3. SUM(NOT positive) равно 0 0 1 0 1 = 2. Вы можете сделать это и в других базах данных, но обычно требуется явное приведение.

Одно предостережение: поскольку MySQL не имеет реального логического типа, ваш positive столбец на самом деле TINYINT(1) , и может содержать любое число, которое помещается в байт, что приведет к сбросу SUM(positive) . Вы можете использовать SUM(NOT NOT positive) , или приведение, или использовать базу данных, которая вам не так сильно врет. 😉

Если все это слишком сложно для вас (и это справедливо), простой выход — немного денормализовать и дать столбцы comments upvotes и downvotes . Или вы могли бы использовать подзапрос для положительных голосов и другой для отрицательных, но, по моему опыту, MySQL особенно плох с операциями группировки и подзапросами.

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

1. Возможно, также захочется объяснить, почему not positive равно -1 . 🙂

2. Спасибо за это, идеально. Изменение таблицы было бы немного затруднительным, потому что это немного больше, чем я выразил, но спорно, потому что sum работает хорошо. В качестве дополнительного примечания, когда вы говорите, что у mysql проблемы с подзапросами, каким образом? Просто недостаток доступных функций или вопрос производительности? Я никогда по-настоящему не рассматривал какие-либо другие базы данных, потому что между ними, казалось, никогда не было существенной разницы.

3. Я не верю, что MySQL всегда может использовать индексы внутри подзапросов, поэтому объединения и GROUP BY и простые сравнения часто выполняются намного медленнее, чем они были бы в противном случае. Недавно я перешел на PostgreSQL, и я вполне доволен этим; открытый исходный код, хорошая поддержка, гораздо меньше ошибок и несколько интересных расширенных функций. Сильно предвзятое сравнение: wiki.postgresql.org/wiki/Why_PostgreSQL_Instead_of_MySQL_2009