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