2010-11-25 54 views
1

这个问题可能已经问了很多次,所以,请原谅我的重复,但我似乎无法找到像这样的东西,也不能设法建立类似于我的东西想要实现。MySQL加入SUM

例如,可以说,我有以下表结构:

//tasks 
+-------+--------------+------+-----+---------+-------+ 
| Field | Type   | Null | Key | Default | Extra | 
+-------+--------------+------+-----+---------+-------+ 
| id | int(11)  | NO | P | None | AI | 
| user | int(11)  | NO |  | None |  | 
| data | varchar(200) | NO |  | None |  | 
+-------+--------------+------+-----+---------+-------+ 

//votes 
+-------+--------------+------+-----+---------+-------+ 
| Field | Type   | Null | Key | Default | Extra | 
+-------+--------------+------+-----+---------+-------+ 
| id | int(11)  | NO | P |   | AI | 
| user | int(11)  | NO |  |   |  | 
| item | int(11)  | NO |  |   |  | 
| up | tinyint(1) | NO |  | 0  |  | 
| down | tinyint(1) | NO |  | 0  |  | 
+-------+--------------+------+-----+---------+-------+ 

数据如下:

//tasks 
+----+------+------------+ 
| id | user | data | 
+----+------+------------+ 
| 1 | 1 | something | 
| 2 | 2 | lorem ip | 
| 3 | 1 | biggy | 
+----+------+------------+ 

//votes 
+----+------+------+----+------+ 
| id | user | item | up | down | 
+----+------+------+----+------+ 
| 1 | 8 | 1 | 1 | 0 | 
| 2 | 4 | 1 | 1 | 0 | 
| 3 | 2 | 1 | 0 | 1 | 
| 4 | 2 | 2 | 1 | 0 | 
| 5 | 1 | 2 | 1 | 0 | 
+----+------+------+----+------+ 

我想要做类似的东西:

SELECT r.* FROM `tasks` WHERE `user` = '1' r 
LEFT JOIN (SELECT SUM(t.up) AS up, 
        SUM(t.down) AS down 
      FROM `votes` t 
      WHERE t.item = r.id) r ON r.id = t.item 

是的,这是我的查询到目前为止,但它不起作用,我不知道如何纠正。

基本上,我想:

  1. 选择一切从表任务其中user为 “x”
  2. 任务加入每一行(在步骤1中选择)与总和的up,总和down来自表其中item等于id任务

这应该产生类似的信息(即。 user = 1):

+----+------+------------+----+------+ 
| id | user | data | up | down | 
+----+------+------------+----+------+ 
| 1 | 1 | something | 3 | 1 | 
| 3 | 1 | biggy | 0 | 0 | 
+----+------+------------+----+------+ 

好了,我希望你们了解并能帮助我。

在此先感谢!

回答

4

WHERE子句需要低于连接,应使用AS声明别名。这是您的查询的(语法)修正版本:

SELECT r.* 
    FROM `tasks` 
LEFT JOIN (
      SELECT SUM(t.up) AS up, 
        SUM(t.down) AS down 
       FROM `votes` AS t 
       WHERE t.item = r.id 
     ) AS r 
     ON r.id = t.item 
    WHERE `user` = '1' 

这是我怎么会做(未经测试):

SELECT `tasks`.`id`, 
      `tasks`.`user`, 
      `tasks`.`data`, 
      `votes`.`up`, 
      `votes`.`down` 
    FROM `tasks` 
LEFT JOIN (
       SELECT `item`, 
         SUM(`up`) AS `up`, 
         SUM(`down`) AS `down` 
       FROM `votes` 
      GROUP BY `item` 
     ) AS `votes` 
     ON `votes`.`item` = `tasks`.`id` 
    WHERE `tasks`.`user` = 1 
+0

事实上这是行不通的,这里的错误:`#1054 - 未知列“,其中clause'`,看起来像线'其中T 'r.id'。 item = r.id`。据我的理解,这是在JOIN之后设置`r`的问题......如果我错了,请纠正我,只是试图从所有这些中学习。 – jolt 2010-11-25 18:31:00

+0

@Tom:你的猜测是正确的。试试我的第二个版本。 – jwueller 2010-11-25 18:40:26

2

让我们看看我的代码是这样的:

SELECT t.id, t.user, t.data, ifnull(u.total, 0) as up, ifnull(d.total, 0) as down 
FROM 
    tasks AS t LEFT OUTER JOIN (
     SELECT item, SUM(up) AS total FROM votes GROUP BY item 
    ) AS u ON t.id = u.item LEFT OUTER JOIN (
     SELECT item, SUM(down) AS total FROM votes GROUP BY item 
    ) AS d ON t.id = u.item 
WHERE t.user = 1; 

然后用于显示单行既总计可以尝试:

SELECT t.id, t.user, t.data, 
    ifnull((SELECT SUM(up) FROM votes GROUP BY item WHERE item = t.id), 0) AS up, 
    ifnull((SELECT SUM(down) FROM votes GROUP BY item WHERE item = t.id), 0) AS down 
FROM tasks AS t 
WHERE t.user = 1; 

或者试试这个:

SELECT t.id, t.user, t.data, IFNULL(tt.up, 0) AS up, IFNULL(tt.down, 0) AS down 
FROM 
    tasks AS t LEFT OUTER JOIN (
     SELECT item, SUM(up) AS up, SUM(down) AS down 
     FROM votes 
     GROUP BY item 
    ) AS tt ON t.id = tt.item 
WHERE t.user = 1