在一个表的两个表中求和儿童

时间:2019-01-21 22:17:21

标签: mysql sql join

我有3张桌子:

a (id,date,ckey) b(id,a.ckey,hht,hha) c(id,a.ckey,date_ini,date_fin)

其中B将所有要完成的活动以及它们各自的小时数保留在2个位置(hht,hha)中,而c保存以其初始日期和最终日期进行的活动(以确定执行日期,减去日期)。

现在我需要知道,对于A中的每条记录,您已分配了多少小时(B)和完成了多少小时(C)

实际上我有这个:

a:

+----------+----------+------------+
|    id    |   date   |     ckey   |
+----------+----------+------------+
|    1     |2018-01-20|     18     |
|----------|----------|------------|

b:

+----------+----------+--------+--------+
|    id    |  a.ckey  |  hht   |   hht  |
+----------+----------+--------+--------+
|    1     |    18    |    2   |    3   |
|    2     |    18    |    2   |    5   |
|    3     |    18    |    0   |    7   |
+----------+----------+--------+--------+

c:

+----------+----------+----------------------+----------------------+
|    id    |  a.ckey  |        date_ini      |        date_fin      |
+----------+----------+----------------------+----------------------+
|    1     |    18    | 2019-01-23 13:30:00  | 2019-01-23 14:00:00  |
|    1     |    18    | 2019-01-23 14:00:00  | 2019-01-23 14:30:00  |
+----------+----------+----------------------+----------------------+

我需要这个:

+----------+----------+----------------------+----------------------+
|    id    |  a.ckey  |         hours        |         hours2       |
+----------+----------+----------------------+----------------------+
|    1     |    18    |           19         |           1          |
+----------+----------+----------------------+----------------------+

我明白了:

+----------+----------+----------------------+----------------------+
|    id    |  a.ckey  |         hours        |         hours2       |
+----------+----------+----------------------+----------------------+
|    1     |    18    |           38         |           37.5       |
+----------+----------+----------------------+----------------------+

这是我的查询

SELECT 
  (b.hht+b.hha) AS hours, 
  (SUM(b.hht+b.hha) - 
    FORMAT(IFNULL((TIMESTAMPDIFF(MINUTE, c.date_ini, c.date_fin)/60),0),2)) AS hours2
FROM a 
LEFT JOIN b ON a.key=b.akey 
INNER JOIN c ON a.key=c.akey 
GROUP a.ckey

3 个答案:

答案 0 :(得分:2)

因为在表bc中有多个行,每个ckey的值都需要在子查询中进行汇总,否则将得到重复的行,从而导致总和不正确。

SELECT a.id, a.key, b.hours, FORMAT(c.minutes/60, 2) AS hours2
FROM a
LEFT JOIN (SELECT akey, SUM(hht+hha) AS hours
           FROM b
           GROUP BY akey) b ON b.akey = a.key
LEFT JOIN (SELECT akey, SUM(TIMESTAMPDIFF(MINUTE, date_ini, date_fin)) AS minutes
           FROM c
           GROUP BY akey) c ON c.akey = a.key
ORDER BY a.id

输出:

id  key     hours   hours2
1   18      19      1.00

Demo on SQLFiddle

答案 1 :(得分:1)

您正在执行m-to-n-join,请尝试使用UNION ALL:

select ckey, sum(hours) as hours, sum(hours) - sum(hours2) as hours2
from
 (
   SELECT ckey, (b.hht+b.hha) AS hours, NULL as hours2
   FROM b
   UNION ALL
   SELECT ckey, NULL AS hours, 
      FORMAT(IFNULL((TIMESTAMPDIFF(MINUTE, c.date_ini, c.date_fin)/60),0),2)) as hours2
   FROM c
 ) as dt
group by ckey

如果您实际上需要表中的列,请将此Select放入派生表中并加入它。

答案 2 :(得分:1)

请检查此

SELECT 
  (SELECT SUM(hha + hht) from b where b.ckey = a.ckey) hours, 
  FORMAT((SELECT SUM(TIMESTAMPDIFF(MINUTE, c.date_ini, c.date_fin)/60) from c where c.ckey = a.ckey),2) as hours2 
FROM A

Fiddle