MySQL SUM以不同的方式

时间:2010-02-02 05:51:37

标签: mysql sum

我有两张桌子

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中与user_raters中的to_id相关的值的总和。查询的结果应为:

| 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 个答案:

答案 0 :(得分:2)

我可能看得太简单了(抱歉我目前无法测试数据),但我猜测以下两个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)

答案 1 :(得分:0)

编辑:@OMG小马删除了他的回答。这种反应现在没有意义,但我不打算删除我的答案,因为我认为这很愚蠢。

@OMG ponies

您的查询会运行,但不会返回任何结果。我必须稍微调整它以在主要查询where子句

中添加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 )
相关问题