日期:2014-05-18  浏览次数:20453 次

请教一个三表查询的问题
有三个表
产品资料表 products p
字段有id,Pro_Name

进仓明细表 storageindtail si
字段有product_id,amount

出仓明细表 storageoutdetail so
字段有product_id,amount

我想统计出 p.product,sum(si.amount)as 入库数量,sum(so.amount)as 出库数量
我用这个语句试过,但入库数量对了,出库数量对不上

select p.pro_name,sum(si.amount)as 入库数量,sum(so.amount)as 出库数量 
from products p left join storageindetail si on p.id=si.product_id left join storageoutdetail so on p.id=so.product_id 
group by p.pro_name

12寸布 12288.00 2640.00
15寸布 NULL NULL
20寸布 200.00 NULL
帆布 4600.00 NULL
花边 1000.00 NULL
钮扣 1300.02 NULL

select p.pro_name,sum(si.amount)as 入库数量 
from products p left join storageindetail si on p.id=si.product_id 
group by p.pro_name

12寸布 12288.00
15寸布 NULL
20寸布 200.00
帆布 4600.00
花边 1000.00
钮扣 1300.02


select p.pro_name,sum(so.amount)as 入库数量 
from products p left join storageoutdetail so on p.id=so.product_id 
group by p.pro_name

12寸布 120.00
15寸布 NULL
20寸布 NULL
帆布 NULL
花边 NULL
钮扣 NULL

两个数差了2000多,这个问题困扰了很久,请各位大侠给个查询方法吧,谢谢大家了

------解决方案--------------------
select p.pro_name,sum(si.amount)as 入库数量,sum(so.amount)as 出库数量
from products p left join storageindetail si on p.id=si.product_id left join storageoutdetail so on p.id=so.product_id
group by p.pro_name

这样统计是不对的.
如果某一连接在某一主键上有N条记录,而相应的另一左连接有一条数据,则另一左连接的统计就会多统计N-1次.
分析一下下面的数据你就能明白了:
SQL code
create table t1(id int,col varchar(10))
insert into t1 select 1,'agbf'
insert into t1 select 2,'fds'
insert into t1 select 3,'vaisud'
create table t2(id int,col int)
insert into t2 select 1,234
create table t3(id int,col int)
insert into t3 select 1,347145
insert into t3 select 1,102201
insert into t3 select 2,874
go
select a.id,sum(b.col)si,SUM(c.col)so
from t1 a left join t2 b on a.id=b.id
left join t3 c on a.id=c.id
group by a.id
select a.id,sum(b.col)si
from t1 a left join t2 b on a.id=b.id
group by a.id
select a.id,SUM(c.col)so
from t1 a left join t3 c on a.id=c.id
group by a.id
/*
id          si          so
----------- ----------- -----------
1           468         449346
2           NULL        874
3           NULL        NULL
警告: 聚合或其他 SET 操作消除了 Null 值。

(3 行受影响)

id          si
----------- -----------
1           234
2           NULL
3           NULL
警告: 聚合或其他 SET 操作消除了 Null 值。

(3 行受影响)

id          so
----------- -----------
1           449346
2           874
3           NULL
警告: 聚合或其他 SET 操作消除了 Null 值。

(3 行受影响)
*/
go
drop table t1,t2,t3