[英]Mysql : JOIN 2 table , one of the SUM is not correct
This is the structure of the two tables 这是两个表的结构
Table A 表A
+----+-----+----+----------------------+--------------------+----------+
| id | ... |....| time_start | time_end | total |
+----+-----+----+----------------------+--------------------+----------+
1 2015-12-06 10:00:00 2015-12-06 12:00:00 200
2 2015-12-07 10:00:00 2015-12-07 12:00:00 300
Table B 表B
+----+----------+------+------+------+------+
| id | idTableA | val1 | val2 | val3 | val4 |
+----+----------+------+------+------+------+
1 1 10 10 10 10
2 1 10 10 10 10
3 2 10 10 10 10
The goal is the following : given a time_start and a time_end date , display the SUM of the totals (table A) and the SUM of the val1,val2,val3,val4 目标如下:给定一个time_start和一个time_end date,显示总计的总和(表A)和val1,val2,val3,val4的总和
Example : 范例 :
time_start = 2015-12-01 00:00:00 time_start = 2015-12-01 00:00:00
time_end = 2015-12-30 23:59:59 time_end = 2015-12-30 23:59:59
Result expected : sum of total = 500 , sum of val(1-4) = 120 预期结果 :总计= 500,val(1-4)等于120
I have tried so : 我已经尝试过了:
$myquery = "";
$myquery .= "SELECT SUM(tableA.total) AS myTotal,";
$myquery .= "SUM(tableB.val1) + SUM(tableB.val2) + SUM(tableB.val3) + SUM(tableB.val4) AS myValTotal ";
$myquery .= "FROM tableA INNER JOIN tableB ON tableA.id = tableB.idTableA ";
$myquery .= "WHERE tableA.time_start >='".$dateStart."' AND tableA.time_end <='".$dateEnd."'";
The SUM of the val(1-4) is correct , but the SUM of total not. val(1-4)的SUM正确,但合计的SUM不正确。
You have to check what kind of data range overlaps you want, if partial or total. 您必须检查想要重叠的数据范围是部分还是全部。
Determine Whether Two Date Ranges Overlap 确定两个日期范围是否重叠
Also the best way to test it is copy the query direct on the db first. 最好的测试方法是首先直接在数据库上复制查询。
Check the data range in the WHERE
在
WHERE
检查数据范围
SET @dateStart= '2015-12-01 00:00:00';
SET @dateEnd = '2015-12-30 23:59:59';
SELECT myTotal, myValTotal
FROM
(
SELECT SUM(tableA.total) AS myTotal
FROM tableA
WHERE tableA.time_start >= @dateStart
AND tableA.time_end <= @dateEnd ;
) T1
CROSS JOIN
(
SELECT SUM(tableB.val1 + tableB.val2 + tableB.val3 + tableB.val4) AS myValTotal
FROM tableA
INNER JOIN tableB
ON tableA.id = tableB.idTableA
WHERE tableA.time_start >= @dateStart
AND tableA.time_end <= @dateEnd
) T2;
You shouldn't aggregate on multiplication of rows . 您不应该在行的乘法上进行汇总。 Rather aggregate two tables independently and then join them, something like:
而是独立地聚合两个表,然后将它们联接起来,例如:
select * from
(
SELECT SUM(tableA.total) AS myTotal
FROM tableA
WHERE tableA.time_start <= @dateEnd
AND tableA.time_end >= @dateStart
) x join (
SELECT SUM(tableB.val1) + SUM(tableB.val2) +
SUM(tableB.val3) + SUM(tableB.val4) AS myValTotal
FROM tableB join tableA ON tableA.id = tableB.idTableA
WHERE tableA.time_start <= @dateEnd
AND tableA.time_end >= @dateStart
) y;
As a starting point, this seems easier to read... 作为起点,这似乎更容易阅读...
$myquery =
"
SELECT SUM(a.total) myTotal
, SUM(b.val1 + b.val2 + b.val3 + b.val4) myValTotal
FROM tableA a
JOIN tableB b
ON b.idTableA = a.id
WHERE a.time_start >='$dateStart'
AND a.time_end <='$dateEnd'
";
SELECT
SUM(tableB.val1) + SUM(tableB.val2) + SUM(tableB.val3) + SUM(tableB.val4) AS myValTotal,
(SELECT SUM(total) from tableA where tableA.time_start >='2015-12-01 00:00:00' AND tableA.time_end <= '2015-12-30 23:59:59') as myTotal
FROM tableA INNER JOIN tableB ON tableA.id = tableB.idTableA
WHERE tableA.time_start >='2015-12-01 00:00:00' AND tableA.time_end <= '2015-12-30 23:59:59'
Aggregate your data before you join, so you don't mistakenly consider values multifold. 在加入数据之前先汇总数据,这样您就不会误认为值是多重的。
select sum(a.total) as mytotal, sum(b.sumval) as myvaltotal
from tablea a
left join
(
select idtablea, sum(val1+val2+val3+val4) as sumval
from tableb
group by idtablea
) b on b.idtablea = a.id
where a.time_start >= @start and a.time_end <= @end;
Here is the same with a subquery in the SELECT clause. 这与SELECT子句中的子查询相同。 It's simpler and circumvents the issue described by Juan Carlos Oropeza in below comments.
它更简单,可以绕开Juan Carlos Oropeza在以下评论中描述的问题。
select
sum(total) as mytotal,
sum((
select sum(val1+val2+val3+val4)
from tableb
where idtablea = tablea.id
)) as sumvaltotal
from tablea
where time_start >= @start and time_end <= @end;
You can declare variable of int type and store the sum values , and again sumup the stored values to get value total 您可以声明int类型的变量并存储总和值,然后再次对存储的值求和以获得总值
declare @val1 int
declare @val2 int
declare @val3 int
declare @val4 int
declare @newval int
select @val1= SUM(isnull(val1,0)) , @val2 =
sum(isnull(val2,0)), @val3=sum(isnull(val3,0)),@val4 =
sum(isnull(val2,0)) from TableB
select @newval = @val1 +@val2+@val3+@val4
@newval will include the sum of val1 to val4 @newval将包括val1与val4之和
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.