Mysql:JOIN 2表,其中一个SUM不正确

时间:2015-12-08 11:45:22

标签: php mysql sql join

这是两个表的结构

表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              

表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

目标如下:给出 time_start time_end 日期,显示总计的总和(表A)和val1的val,val2, VAL3,VAL4

示例

  • time_start = 2015-12-01 00:00:00

  • time_end = 2015-12-30 23:59:59

预期结果:总和= 500,总和(1-4)= 120

我试过了:

$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."'";

val(1-4)的SUM是正确的,但是总和不是。

6 个答案:

答案 0 :(得分:0)

您必须检查所需的数据范围重叠,如果是部分或全部。

Determine Whether Two Date Ranges Overlap

另外,测试它的最佳方法是首先直接在db上复制查询。

检查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;

答案 1 :(得分:0)

您不应在行的乘法上进行汇总。而是独立地聚合两个表然后加入它们,例如:

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;

答案 2 :(得分:0)

作为一个起点,这似乎更容易阅读...

    Dim jsonString = "{""items"":{""1"":[{""text"":""Man"",""itemID"":""1"",""checked"":1,""sequence"":1,""matchingtext"":"""",""weight"":0},{""text"":""goat"",""itemID"":""2"",""checked"":0,""sequence"":2,""matchingtext"":"""",""weight"":0},{""text"":""dog"",""itemID"":""3"",""checked"":0,""sequence"":3,""matchingtext"":"""",""weight"":0}],""2"":[{""text"":""pizza"",""itemID"":""1"",""checked"":1,""sequence"":1,""matchingtext"":"""",""weight"":0},{""text"":""horse"",""itemID"":""2"",""checked"":0,""sequence"":2,""matchingtext"":"""",""weight"":0},{""text"":""paper"",""itemID"":""3"",""checked"":0,""sequence"":3,""matchingtext"":"""",""weight"":0}]},""wbmode"":""dd"",""wbanswertype"":""sc""}"

    Dim j As JObject = JObject.Parse(jsonString)

    For Each item As JProperty In j.Item("items")
        Dim itemObjects As JToken = item.Value
        For Each i As JObject In itemObjects
            For Each p In i
                Debug.Print(p.Key.ToString & " = " & p.Value.ToString)
            Next
        Next
    Next

答案 3 :(得分:0)

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'

答案 4 :(得分:0)

在加入之前汇总数据,因此不要错误地将值视为多倍。

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;

SELECT子句中的子查询与此相同。它更简单,并且在下面的评论中绕过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;

答案 5 :(得分:0)

你可以声明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将包括val1到val4的总和