SQL如何使用SUM和Group By与多个表?

时间:2017-11-21 16:09:47

标签: mysql sql

我有三张桌子。

对于每个“id”值,我想要col1值的总和,col2值和&的总和。 col3值的总和单独列出。我不是在桌子上总结。

table a
num  | id  |  col1
================
1     100     0
2     100     1
3     100     0

1     101     1
2     101     1
3     101     0

table b
idx  | id  | col2
=================
1     100    20
2     100    20
3     100    20

4     101   100
5     101   100

table c
idx | id | col3
==============================
1     100     1 
2     100     1
3     100     1

4     101    10
5     101     1

我希望结果看起来像这样,

ID | sum_col1 | sum_col2 | sum_col3
====================================
100      1         60          3    
101      2        200         11

这是我的查询,它运行时间太长,然后超时。我的表大约有25,000行。

SELECT a.id as id,
SUM(a.col1) as sum_col1,
SUM(b.col2) as sum_col2,
SUM(c.col3) as sum_col3 
FROM a, b, c
WHERE a.id=b.id
AND a=id=c.id
GROUP by id 
Order by id desc

每个表中的行数可能不同,但每个表中“id”值的范围是相同的。

这似乎是一个类似的问题,但我无法使其发挥作用,

Mysql join two tables sum, where and group by

3 个答案:

答案 0 :(得分:1)

也许会这样做?

没有机会运行它,但我认为它可以完成这项工作。

SELECT sumA.id, sumA.sumCol1, sumB.sumCol2, sumC.sumCol3
FROM
(SELECT id, SUM(col1) AS sumCol1 FROM a GROUP BY id ORDER BY id ASC) AS sumA
JOIN (SELECT id, SUM(col2) AS sumCol2 FROM b GROUP BY id ORDER BY id ASC) AS sumB ON sumB.id = sumA.id
JOIN (SELECT id, SUM(col3) AS sumCol3 FROM c GROUP BY id ORDER BY id ASC) AS sumC ON sumC.id = sumB.id
;

修改

SELECT IF(sumA.id IS NOT NULL, sumA.id, IF(sumB.id IS NOT NULL, sumB.id, IF(sumC.id IS NOT NULL, sumC.id,''))),,
sumA.sumCol1, sumB.sumCol2, sumC.sumCol3
FROM
(SELECT id, SUM(col1) AS sumCol1 FROM a GROUP BY id ORDER BY id ASC) AS sumA
OUTER JOIN (SELECT id, SUM(col2) AS sumCol2 FROM b GROUP BY id ORDER BY id ASC) AS sumB ON sumB.id = sumA.id
OUTER JOIN (SELECT id, SUM(col3) AS sumCol3 FROM c GROUP BY id ORDER BY id ASC) AS sumC ON sumC.id = sumB.id
;

答案 1 :(得分:1)

以下是基于您的数据的解决方案。您的查询的问题是您正在连接非唯一列上的表,从而产生笛卡尔积。

数据

SELECT a_sum.id, col1_sum, col2_sum, col3_sum
 FROM (SELECT id, SUM(col1) AS col1_sum
         FROM a
        GROUP BY id ) a_sum
      JOIN 
      (SELECT id, SUM(col2) AS col2_sum
         FROM b
        GROUP BY id ) b_sum 
      ON (a_sum.id = b_sum.id)
      JOIN 
      (SELECT id, SUM(col3) AS col3_sum
         FROM c
        GROUP BY id ) c_sum 
      ON (a_sum.id = c_sum.id);

解决方案

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);



    DatabaseReference ref = FirebaseDatabase.getInstance().getReference();

    ref.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            String Active = dataSnapshot.child("snaresense").child("strings").child("StringActive").getValue(String.class);
            String BatteryLevel = dataSnapshot.child("snaresense").child("strings").child("StringBatteryLevel").getValue(String.class);
            String TrapId = dataSnapshot.child("snaresense").child("strings").child("StringTrapId").getValue(String.class);
            String fireData = ("Hello. Trap: "+TrapId+" has been activated. The battery level is: "+BatteryLevel);
            String usrnum = dataSnapshot.child("snaresense").child("strings").child("StringPhoneNum").getValue(String.class);
            sendMsg (usrnum, fireData);

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

结果符合预期

enter image description here

注意:如果所有三个表中都不存在id,请执行外连接。

答案 2 :(得分:0)

我会首先进行求和,然后将结果合并,然后将它们转动:

SELECT
  id,
  MAX(CASE WHEN which = 'a' then sumof end) as sum_a,
  MAX(CASE WHEN which = 'b' then sumof end) as sum_b,
  MAX(CASE WHEN which = 'c' then sumof end) as sum_c
FROM
(
  SELECT id, sum(col1) as sumof, 'a' as which FROM a GROUP BY id
  UNION ALL
  SELECT id, sum(col2) as sumof, 'b' as which FROM b GROUP BY id
  UNION ALL
  SELECT id, sum(col3) as sumof, 'c' as which FROM c GROUP BY id
) a
GROUP BY id

你也可以结合,然后总结:

SELECT
  id,
  SUM(CASE WHEN which = 'a' then v end) as sum_a,
  SUM(CASE WHEN which = 'b' then v end) as sum_b,
  SUM(CASE WHEN which = 'c' then v end) as sum_c
FROM
(
  SELECT id, col1 as v, 'a' as which FROM a GROUP BY id
  UNION ALL
  SELECT id, col2 as v, 'b' as which FROM b GROUP BY id
  UNION ALL
  SELECT id, col3 as v, 'c' as which FROM c GROUP BY id
) a
GROUP BY id

你不能轻易使用连接,除非所有的表都包含ID的所有值,在这种情况下我会说你可以将它们作为子查询加起来然后将结果连接在一起..但是如果一个您的表突然缺少其他两个表所具有的id值,该行将从您的结果中消失(除非您在ON子句中使用完全外连接和一些非常丑陋的合并)

在这种情况下使用union将为您提供更多缺失值容忍的结果集,因为它可以处理任何表中缺少的ID值。因此,我们将表合并为一个数据集,但使用常量来跟踪值来自哪个表,这样我们可以在以后将其选择为自己的总和

如果任何表中不存在任何id值,则该列的总和将为null。如果希望它为0,则可以将MAX更改为SUM或将MAX包装在COALESCE中