【问题标题】:Calculate sum on the records while joining two tables with a third table在将两个表与第三个表连接时计算记录的总和
【发布时间】:2017-10-02 19:19:36
【问题描述】:

我有三张桌子:

mysql> select * from a;
+----+---------+
| ID | Name    |
+----+---------+
|  1 | John    |
|  2 | Alice   |
+----+---------+

mysql> select * from b;
+------+------------+----------+
| UID  | date       | received |
+------+------------+----------+
|    1 | 2017-10-02 |        5 |
|    1 | 2017-09-30 |        1 |
|    1 | 2017-09-29 |        4 |
+------+------------+----------+

mysql> select * from c;
+------+------------+------+
| UID  | date       | sent |
+------+------------+------+
|    1 | 2017-09-25 |    7 |
|    1 | 2017-09-30 |    2 |
|    1 | 2017-09-29 |    3 |
+------+------------+------+

如果我尝试计算为 John 发送的总数,则为 12。而对于已接收,则为 10。 但是如果我尝试加入所有三个表,结果很奇怪。这是我连接三个表的查询:

mysql> select sum(sent), sum(received) from a
    -> join c on c.UID = a.ID
    -> join b on b.UID = a.ID
    -> where a.ID = 1;
+-----------+---------------+
| sum(sent) | sum(received) |
+-----------+---------------+
|        36 |            30 |
+-----------+---------------+

但我需要正确的数字(分别为 12 和 10)。我怎样才能得到正确的数字?

【问题讨论】:

    标签: mysql sql query-optimization


    【解决方案1】:

    你应该加入聚合结果而不是原始表

    select a.uid, t1.received, t2.sent
    from a
    inner join (
        select uid, sum(received) received
        from b 
        group by uid
        ) t1 on t1.uid = a.id
    inner join (
        select uid, sum(sent) sent
        from c 
        group by uid
        ) t2 on t2.uid = a.id
     where a.id = 1
    

    【讨论】:

    • 抛出一个期望:“字段列表”中的未知列“已发送”。
    • 有没有办法避免子查询?
    • 为了得到正确的结果,不......如果你尝试直接加入表格,你会在表格行之间得到一个笛卡尔积(你得到 3 倍的总和,因为你有 3 行......尝试使用4 或 5 行)
    • @Amir - from 子句中的子查询很好,不要避免使用它们。
    • @scaisEdge - 查询错误 - sent 来自 c
    【解决方案2】:

    你可以试试下面

    select bx.id, recieved, sum(c.sent) sent from
    (
    SELECT a.id, sum(b.received) recieved
    from a 
    INNER JOIN b 
    ON a.id=b.uid
    group by a.id
    ) bx
    INNER JOIN c 
    ON c.uid=bx.id 
    group by bx.id, bx.recieved;
    

    >>>Demo<<<

    【讨论】:

    • 相同的结果,30 和 36。
    • @Amir 你现在可以试试。
    • 谢谢,拉维。有没有办法避免子查询?
    • @Amir 实际上并不完全,但我尝试并避免了一个子查询。
    【解决方案3】:

    这摆脱了子查询,但引入了一些你可能不想要的东西:

    ( SELECT  uid, 'Received' AS direction, SUM(received) AS HowMany
          WHERE  uid = 1
          GROUP BY uid )
    UNION ALL
    ( SELECT  uid, 'Sent' AS direction, SUM(sent) AS HowMany
          WHERE  uid = 1
          GROUP BY uid )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-27
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多