SQL:简单的汇总查询,并连接到其他两个表

时间:2019-04-22 10:26:13

标签: sqlite spatialite

我在sqlite中有3张桌子,如下所示:

表1

ID | x
1, 2.0
2, 3.0
3, 4.0
4, 3.0

表2

join_ID | x
1, 5.0
1, 6.0
2, 5.0
2, 2.0
3, 2.0
4, 2.0

表3

join_ID | x
4, 5.0
1, 6.0
3, 5.0
2, 2.0
2, 2.0
1, 2.0

我想要获得一个表,如下所示:

ID | x | x_agg
1, 2, 21
2, 3, 14
3, 4, 11
4, 3, 10

其中x表示包含一致ID的所有行的总和。本质上,这是我想要实现的计算:

第1行-> 2 + 5 + 6 + 6 + 2 = 21

第2行-> 3 + 5 + 2 + 2 + 2 = 14

第3行-> 4 + 2 + 5 = 11

第4行-> 3 + 2 + 5 = 10

我正在QGIS的DBManager中使用sqlite(通过spacespaceite)。上面是我构想的一个有限的工作示例,但应该复制我正在工作的条件。我想出了以下代码:

 select
  table1.ID,
  ifnull(table1.x,0) as x,
  SUM(ifnull(table2.x,0)) +SUM(ifnull(table3.x,0))+ifnull(table1.x,0) as x_agg
from
 table1
  left join table2 on table1.ID = table2.join_ID
  left join table3 on table1.ID = table3.join_ID
group by
  ID;

但是得到:

ID  x   x_agg
1   2.0 40.0
2   3.0 25.0
3   4.0 11.0
4   3.0 10.0

当我运行以上命令时。我在这里做错了什么?

2 个答案:

答案 0 :(得分:2)

这里可能最简单的方法是只加入两个单独的子查询,这些子查询分别汇总第二张和第三张表:

SELECT
    t1.ID,
    t1.x,
    COALESCE(t2.sum_x, 0) + COALESCE(t3.sum_x, 0) AS x_agg
FROM table1 t1
LEFT JOIN
(
    SELECT join_ID, SUM(x) AS sum_x
    FROM table2
    GROUP BY join_ID
) t2
    ON t1.ID = t2.join_ID
LEFT JOIN
(
    SELECT join_ID, SUM(x) AS sum_x
    FROM table3
    GROUP BY join_ID
) t3
    ON t1.ID = t3.join_ID;

请注意,我在两个地方都使用了左联接,因为来自第一个表的给定ID可能不会出现在其他两个表中的任何一个中。在这种情况下,有效总和应视为零。

答案 1 :(得分:1)

那又如何,将表的总和全部添加到外部SELECT的行部分而没有任何联接呢?

SELECT id
     , ifnull(x, 0) as x
     , ifnull(x, 0)
         + (SELECT total(x) FROM table2 AS t2 WHERE t1.id = t2.join_id)
         + (SELECT total(x) FROM table3 AS t3 WHERE t1.id = t3.join_id) AS x_agg
FROM table1 AS t1
ORDER BY id;
id          x           x_agg     
----------  ----------  ----------
1           2           21.0      
2           3           14.0      
3           4           11.0      
4           3           10.0      
  • sum()total():两者都返回所有非空值的总和,但是对于每个值均为null的情况,sum()返回null,而total()返回0.0 。

使用以下数据(请注意使用索引来改善相关的子查询):

CREATE TABLE table1(id INTEGER PRIMARY KEY, x NUMERIC);
INSERT INTO table1 VALUES(1,2);
INSERT INTO table1 VALUES(2,3);
INSERT INTO table1 VALUES(3,4);
INSERT INTO table1 VALUES(4,3);
CREATE TABLE table2(join_id INTEGER, x NUMERIC);
INSERT INTO table2 VALUES(1,5);
INSERT INTO table2 VALUES(1,6);
INSERT INTO table2 VALUES(2,5);
INSERT INTO table2 VALUES(2,2);
INSERT INTO table2 VALUES(3,2);
INSERT INTO table2 VALUES(4,2);
CREATE TABLE table3(join_id INTEGER, x NUMERIC);
INSERT INTO table3 VALUES(4,5);
INSERT INTO table3 VALUES(1,6);
INSERT INTO table3 VALUES(3,5);
INSERT INTO table3 VALUES(2,2);
INSERT INTO table3 VALUES(2,2);
INSERT INTO table3 VALUES(1,2);
CREATE INDEX table2_join_id_idx ON table2(join_id);
CREATE INDEX table3_join_id_idx ON table3(join_id);