MySQL加入SUM

时间:2010-11-25 18:17:42

标签: mysql join

这个问题可能已被问过很多次了,因此,请原谅我复制,但我似乎无法找到类似这样的东西,也无法建立类似于我想要实现的东西。

例如,假设我有以下表结构:

//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等于{em> tasks
  3. id

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

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

    嗯,我希望你们明白并且可以帮助我。

    提前致谢!

2 个答案:

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

答案 1 :(得分: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