用于求和多个表的列的SQL查询

时间:2014-12-19 11:34:40

标签: sql sql-server select group-by left-join

我认为这会很容易,但它让我感到困惑,我不知道正确的解决方案。让我来代表一下这个问题。以下是表格和数据:

create table table1 (ID int primary key, total int);
insert into table1 values (1, 100);
insert into table1 values (2, 150);

create table table2 (ID int primary key, table1_ID int, total int);
insert into table2 values(1, 1, 10);
insert into table2 values(2, 1, 20);
insert into table2 values(3, 1, 40);

create table table3 (ID int primary key, table2_ID int, total int);
insert into table3 values(1, 1, 1000);
insert into table3 values(2, 1, 1000);
insert into table3 values(3, 2, 2000);
insert into table3 values(4, 2, 2000);

我需要编写一个SQL查询,如果有任何总计,将列出table1以及表2和表3的总计。

如果它只有table1和table2,那么这个查询工作正常:

select table1.ID, table1.total, sum(table2.total) from table1
left outer join table2 on table1.ID = table2.table1_ID
group by table1.ID, table1.total;

结果是正确的:
1 100 70
2 150 null

但是,如果我尝试包含table3:

select table1.ID, table1.total, sum(table2.total), sum(table3.total) from table1
left outer join table2 on table1.ID = table2.table1_ID
left outer join table3 on table2.ID = table3.table2_ID
group by table1.ID, table1.total

我得到了这个结果:
1 100 100 6000
2 150 null null

表2的总和不正确,因为与表3的连接乘以其行,值10和值20相加两次。如何更正此SQL查询?

在我的现实生活中,我实际上有table4和table5。

4 个答案:

答案 0 :(得分:2)

您需要预先聚合每个维度的值。你得到的是笛卡尔积,它会抛出总和:

select t1.ID, t1.t1_total, t2.t2_total, t3.t3_total
from table1 t1 left join
     (select t2.table1_id, sum(t2.total) as t2_total
      from table2 t2
      group by t2.table1_id
     ) t2
     on t1.id = t2.table1_id left join
     (select t2.table1_id, sum(t3.total) as t3_total
      from table2 t2 join
           table3 t3
           on t2.id = t3.table2_id
      group by t2.table1_id
     ) t3
     on t1.id = t3.table1_id;

换句话说,在进行连接之前将所有内容都设置为table1.id 的级别,因此连接不会不必要地增加行数。

答案 1 :(得分:1)

试试这个:

SELECT t1.ID, t1.total, 
       SUM(ISNULL(t2.total, 0)) AS t2Total, 
       SUM(ISNULL(t3.total, 0)) AS t3Total 
FROM table1 t1
LEFT OUTER JOIN table2 t2 ON t1.ID = t2.table1_ID
LEFT OUTER JOIN (SELECT t3.table2_ID, SUM(t3.total) AS total 
                 FROM table3 t3
                 GROUP BY t3.table2_ID
                ) AS t3 ON t2.ID = t3.table1_ID
GROUP BY t1.ID, t1.total;

答案 2 :(得分:0)

for sql server 2012

    DECLARE @x table(id int,total int,stotal int)
    INSERT INTO @x
    SELECT id,total,sum(total)
    FROM table1 
    UNION
    SELECT id,total,sum(total)
    FROM table2
    UNION
    SELECT id,total,sum(total)
    FROM table3

    SELECT id,total,lead(sum(stotal))
    FROM @x

答案 3 :(得分:0)

SELECT 
    table1.ID, 
    table1.total,
    total2,
    total3
FROM 
    table1
CROSS APPLY
(
    SELECT
        SUM(table2.total) as total2
    FROM
        table2
    WHERE 
        table1_ID = table1.ID
) AS T1
CROSS APPLY
(
    SELECT 
        SUM(table3.total) as total3
    FROM
        table3
    INNER JOIN
        table2
    ON
        table3.table2_ID = table2.ID
    WHERE
        table2.table1_ID = table1.ID
) AS T2