2013-02-25 38 views
2

所以我有这样的SQL代码,我想显示其收费单,并在他们收到的每个项目的总和:跨乘法表

select item_description, sum(receipt_qty) as Samp1, sum(chargeSlip_qty) as Samp2 
from Items inner join Receipt_Detail on (Receipt_Detail.item_number = 
    Items.item_number) 
inner join ChargeSlip_Detail on (ChargeSlip_Detail.item_number = 
    Items.item_number) 
group by item_description 

它产生这样的输出:

Acetazolamide 2681 1730 
Ascorbic Acid 1512 651 
Paracetamol 1370 742 
Silk   576 952 

但它应该是:

Acetazolamide 383 173 
Ascorbic Acid 216 93 
Paracetamol 274 106 
Silk   96 238 

我的代码出了什么问题?

回答

2

由于您正在加入表格,因此当您获取sum()时,您可能会遇到一对一的关系,从而导致问题。所以你可以使用子查询来获得结果。这将得到sum()receiptchargeslip每个item_number,然后你加入该回你items表得到最终的结果是:

select i.item_description, 
    r.Samp1, 
    c.Samp2 
from Items i 
inner join 
(
    select sum(receipt_qty) Samp1, 
    item_number 
    from Receipt_Detail 
    group by item_number 
) r 
    on r.item_number = i.item_number 
inner join 
(
    select sum(chargeSlip_qty) Samp2, 
    item_number 
    from ChargeSlip_Detail 
    group by item_number 
) c 
    on c.item_number = i.item_number 
+0

finnaly解决我的问题:)谢谢先生! – 2013-02-25 14:00:40

0
Item_Number执行分组依据,第一,

,让你不乘以Receipt_DetailChargeSlip_Detail。也就是说,你加入回Items

select 
    I.item_description, 
    R.Samp1, 
    C.Samp2 
from 
    Items I 
    inner join 
    (SELECT item_number, sum(receipt_qty) as Samp1 
     FROM Receipt_Detail 
     GROUP BY item_number 
    ) R 
     on (R.item_number = I.item_number) 
    inner join 
    (SELECT item_number, sum(chargeSlip_qty) as Samp2 
     FROM ChargeSlip_Detail 
     GROUP BY item_number 
    ) C 
     on (C.item_number = I.item_number) 
0

左前生成每个Item_Number值的总和左表联接返回行,并在左边的表的每一行,在右边的表中的所有匹配的行。

因此,例如:

create table Customers (name varchar(50)); 
insert Customers values 
    ('Tim'), 
    ('John'), 
    ('Spike'); 
create table Orders (customer_name varchar(50), product varchar(50)); 
insert Orders values (
    ('Tim', 'Guitar'), 
    ('John', 'Drums'), 
    ('John', 'Trumpet'); 
create table Addresses (customer_name varchar(50), address varchar(50)); 
insert Addresses values (
    ('Tim', 'Penny Lane 1'), 
    ('John', 'Abbey Road 1'), 
    ('John', 'Abbey Road 2'); 

然后,如果你运行:

select c.name 
,  count(o.product) as Products 
,  count(a.address) as Addresses 
from Customers c 
left join Orders o on o.customer_name = c.name 
left join Addresses a on a.customer_name = c.name 
group by name 

你得到:

name Products Addresses 
Tim  1   1 
John 4   4 
Spike 0   0 

但约翰没有4级的产品!
如果没有group by运行,你可以看到为什么计数是关闭:

select * 
from Customers c 
left join Orders o on o.customer_name = c.name 
left join Addresses a on a.customer_name = c.name 

你得到:

name customer_name product  customer_name address 
Tim  Tim    Guitar  Tim    Penny Lane 1 
John John   Drums  John   Abbey Road 1 
John John   Drums  John   Abbey Road 2 
John John   Trumpet  John   Abbey Road 1 
John John   Trumpet  John   Abbey Road 2 
Spike NULL   NULL  NULL   NULL 

正如你所看到的,加入最终重复对方。对于每个产品,重复地址列表。这给你错误的数字。为了解决这个问题,使用优秀的其他答案之一:

select c.name 
,  o.order_count 
,  a.address_count 
from Customers c 
left join 
     (
     select customer_name 
     ,  count(*) as order_count 
     from Orders 
     group by 
       customer_name   
     ) o 
on  o.customer_name = c.name 
left join 
     (
     select customer_name 
     ,  count(*) as address_count 
     from Addresses 
     group by 
       customer_name   
     ) a 
on  a.customer_name = c.name 

子查询确保只有一行每个客户加入。结果好多了:

name order_count address_count 
Tim  1   1 
John 2   2 
Spike NULL  NULL