MySQL SUM по-разному - PullRequest
       15

MySQL SUM по-разному

1 голос
/ 02 февраля 2010

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

user_raters:

| id(int) | to_id(int) | value(int) | created_at(datetime)
|1        | 2          | 1          | 2009-03-01 00:00:00

РЕДАКТИРОВАТЬ: я изменил user_rater_id. history_user_raters.user_rater_id связан с user_raters.id

history_user_raters:

| id(int) | user_rater_id(int) | value(int) | created_at(datetime)
| 1       | 1                  | 1          | 2009-03-02 00:00:00
| 2       | 1                  | 1          | 2009-03-02 00:00:00
| 3       | 1                  | -1         | 2009-03-02 00:00:00
| 4       | 1                  | 1          | 2009-03-03 00:00:00
| 5       | 1                  | -1         | 2009-03-03 00:00:00
| 6       | 1                  | -1         | 2009-03-03 00:00:00
| 7       | 1                  | -1         | 2009-03-03 00:00:00

Я хочу посчитать сумму значений из history_user_raters, поскольку она связана с to_id из user_raters. Результат запроса должен быть:

| year | month | day | total | down | up
| 2009 | 3     | 2   | 1     | 1    | 2
| 2009 | 3     | 3   | -2    | 3    | 1

У меня есть запрос, который близок, но он неправильно считает вверх и вниз. Всего правильно. Может ли кто-нибудь помочь мне написать запрос или новый запрос, который вычисляет правильные значения вверх и вниз?

Мой текущий запрос:

SELECT 
 YEAR(history.created_at) AS `year`,
 MONTH(history.created_at) AS `month`,
 DAY(history.created_at) AS `day`,
 SUM(history.value) as `total`,

 (SELECT 
  abs(SUM(historydown.value)) 
 FROM `user_raters` as raterdown 
  INNER JOIN `history_user_raters` AS historydown 
 WHERE raterdown.to_id = 2 
  AND historydown.value = -1 
  AND date(historydown.created_at) 
 GROUP BY history.created_at) as down,

 (SELECT SUM(historyup.value) 
 FROM `user_raters` as raterup 
  INNER JOIN `history_user_raters` AS historyup 
 WHERE raterup.to_id = 2 
  AND historyup.value = 1  
  AND date(history.created_at) 
 GROUP BY raterup.to_id) as up 

FROM `user_raters` 
 INNER JOIN history_user_raters AS history ON user_raters.id = history.user_rater_id
WHERE (user_raters.to_id = 2) 
GROUP BY DATE(history.created_at)

Ответы [ 2 ]

2 голосов
/ 02 февраля 2010

Я могу видеть это слишком просто (и извините, я не могу проверить данные на данный момент), но я предполагаю, что следующий трюк с двумя операторами CASE сделает то, что нужно

SELECT 
  YEAR(history.created_at) AS year,
  MONTH(history.created_at) AS month,
  DAY(history.created_at) AS day,
  SUM(history.value) as total,
  SUM(CASE WHEN history.value < 0 THEN history.value ELSE 0 END) as down,
  SUM(CASE WHEN history.value > 0 THEN history.value ELSE 0 END) as up
FROM `user_raters` 
INNER JOIN `history_user_raters` AS history
  ON user_raters.id = history.user_rater_id
WHERE (user_raters.to_id = 1)  -- or some other condition...
GROUP BY DATE(history.created_at)
0 голосов
/ 02 февраля 2010

РЕДАКТИРОВАТЬ: @OMG Пони удалил свой ответ. Этот ответ сейчас не имеет смысла, но я не собираюсь удалять свой ответ, потому что считаю его глупым.

@ OMG пони

Ваш запрос выполняется, но не возвращает результатов. Мне пришлось немного его настроить, чтобы добавить to_id в основные запросы, где предложение

SELECT 
 YEAR( t.created_at ) AS `year` , 
 MONTH( t.created_at ) AS `month` , 
 DAY( t.created_at ) AS `day` , 
 SUM( t.value ) AS `total` , 
 MAX( COALESCE( x.sum_down, 0 ) ) AS down, 
 MAX( COALESCE( y.sum_up, 0 ) ) AS up
FROM history_user_raters AS t
JOIN user_raters AS ur ON ur.to_id = t.user_rater_id
LEFT JOIN (

 SELECT hur.user_rater_id, 
  SUM( hur.value ) AS sum_down
 FROM history_user_raters AS hur
 WHERE hur.value = -1
 GROUP BY hur.user_rater_id
) AS x ON x.user_rater_id = t.user_rater_id
LEFT JOIN (

 SELECT hur.user_rater_id, 
  SUM( hur.value ) AS sum_up
 FROM history_user_raters AS hur
 WHERE hur.value =1
 GROUP BY hur.user_rater_id
) AS y ON y.user_rater_id = t.user_rater_id
WHERE ur.to_id =1
GROUP BY YEAR( t.created_at ) , MONTH( t.created_at ) , DAY( t.created_at )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...