MySQL SUM по запросу с множественными значениями - PullRequest
1 голос
/ 10 января 2012

У меня есть следующий запрос:

$strQuery = "SELECT siteid, SUM(watts) AS wattage, unit, device, time FROM inverter WHERE siteid = '528' AND time Between '$time1' AND '$time2' Order By device Asc";

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

На графике я отображаю устройство в качестве метки имени оси X и мощность в качестве значения.

Спасибо

Ответы [ 3 ]

5 голосов
/ 10 января 2012

SUM() - агрегатная функция, которую следует использовать вместе с оператором GROUP.Если оператор GROUP пропущен, все выбранные строки агрегируются в группу.

см. Документы: http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html

Просмотр оператора GROUP BY:

SELECT siteid, device, 
  SUM(watts) AS wattage, 
  MIN(time) as start_time, 
  MAX(time) as end_time 
  unit
FROM inverter
WHERE siteid = '528' 
  AND time BETWEEN '$time1' AND '$time2'
GROUP BY device, unit
ORDER BY device ASC

Кроме того, когда вы используете агрегацию и выбираете поля, которые не содержатся в операторе GROUP (здесь: время), вы должны убедиться, что вы действительно получаете желаемое значение.

Значения агрегированной строки, которую вы получаете для каждого устройства, рассчитываются с использованием множества строк с возможно отдельными значениями в этих полях.Если вы не используете статистическую функцию (MIN, MAX, AVG, ..), чтобы определить, какое из нескольких значений должна содержать ваша агрегированная строка, вы получите значение, выбранное более или менее случайным образомMySQL.

Вы должны либо

  • не выбирать такое поле, когда в этом нет необходимости.(например, время)
  • использовать соответствующую статистическую функцию (MIN, MAX, AVG, ..) для каждого поля, которое не содержится в предложении GROUP BY, чтобы убедиться, что вы получаете правильное значение,(здесь я вставил время начала и окончания для временного промежутка измерения, используя MIN и MAX)
  • или включив его в предложение GROUP BY (я сделал это для "единицы" в примере, потому чтовы получаете неправильный результат при использовании SUM как в мегаваттах, так и в киловаттах. Я предполагаю, что для этого вы используете «единицу измерения»?и не детерминированный.
4 голосов
/ 10 января 2012

Вы можете просто использовать простой запрос, предложенный @Kaii и @ cairnz.

Однако, , если несколько раз и единиц для выбранных устройств, MySQL просто выберетединица и время от одного устройства более или менее наугад.

Почему ваш запрос не удался
Использование использует агрегатную функцию.
Если вы не укажете предложение group by, агрегатная функция просто добавит все строки в 1 агрегат.
Все строки, не охваченные агрегатной функцией, будут сведены в один элемент (одна будет просто выбрана на досуге).

Чтобы увидеть, какие данные лежат ниже, я предлагаю сделать следующее:

SELECT 
  siteid
  , SUM(watts) AS wattage
  , GROUP_CONCAT(DISTINCT unit) as units
  , device
  , GROUP_CONCAT(time) as times 
FROM inverter 
WHERE siteid = '528' 
  AND time BETWEEN '$time1' AND '$time2' 
GROUP BY device
ORDER BY device ASC  

Функция агрегирования GROUP_CONCAT покажет список всех значений (DISTINCT), разделенных запятыми, которые объединены вместеагрегация.
Поскольку вы группируете только по device, вы будете объединять различные типы unit s и time s.
Чем больше столбцов вы добавите в предложение group by, тем большеВы «увеличите» данные, и будет показано больше строк.

Почему вы должны быть осторожны при перечислении «голых» столбцов в списке выбора, которых нет в group by
Если вы перечисляете «голые» столбцы (т.е. не как частьагрегированное выражение), которые не перечислены в group by выражениях и , эти столбцы функционально не зависят от предложения group by.
Будет несколько разных значений, из которых будет показано только одно.
Это поведение уникально для MySQL, большинство других разновидностей SQL выдаст ошибку и откажется.

Причина, по которой MySQL допускает это опасное поведение, заключается в том, что
A: он позволяет выполнять более быстрые запросы,
B: если вы укажете уникальный ключ в предложении group by,другие поля будут функционально зависеть от этого ключа (см. ANSI SQL 2003), и указание большего количества полей не имеет смысла,
C: иногда вас не интересуют значения этих других полей, и вам нужно отобразить случайный представитель.,

Почему я не могу просто перечислить все неагрегированные столбцы в группе с помощью
Если вы измените оператор group by, это окажет глубокое влияние на вывод.
Чем больше столбцов (вплоть до того момента, когда вы нажмете уникальный ключ для выбранных столбцов) вы group by, тем больше деталей вы получите, что сводит на нет весь смысл использования агрегатных функций.

Решение
Если вы просто хотите показать случайную единицу и время, это, конечно, здорово, но, возможно, имеет смысл использовать следующий запрос:

SELECT 
  siteid
  , SUM(watts) AS wattage
  , COUNT(*) as NumberOfUnits
  , device
  , MIN(time) as Mintime
  , MAX(time) as Maxtime
FROM inverter 
WHERE siteid = '528' 
  AND time BETWEEN '$time1' AND '$time2' 
GROUP BY device
ORDER BY device ASC  

Творческое использование агрегатных функций в вашем распоряжении - это ответ, см .: http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html

Поскольку вы используете MySQL, я особенно благодарен.рекомендуем изучать GROUP_CONCAT очень универсальную и полезную функцию.

1 голос
/ 10 января 2012

Вы должны указать, что группировать по:

SELECT 
 siteid, 
 SUM(watts) AS wattage, 
 unit, 
 device, 
 MIN(time) AS StartTime,
 MAX(time) AS EndTime

FROM inverter 

WHERE siteid = '528' AND time Between '$time1' AND '$time2' 
GROUP BY siteid, unit, device
Order By device Asc

РЕДАКТИРОВАТЬ: Использование MIN() и MAX() для времени позволяет вам видеть, какие временные интервалы охватывают SUM() обложки. Вы не должны использовать время отдельно в запросе, не указав, сколько времени показывает сумма мощности для комбинации устройства / устройства.

...