交叉乘法表

时间:2013-02-25 13:00:20

标签: sql

我有这个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

我的代码出了什么问题?

3 个答案:

答案 0 :(得分:2)

由于您正在加入表,因此当您获得sum()时,您可能会遇到导致问题的一对多关系。因此,您可以使用子查询来获取结果。对于每个sum(),这将获得receiptchargeslip的{​​{1}},然后将其加入到您的item_number表中以获得最终结果:< / p>

items

答案 1 :(得分:0)

首先按Item_Number执行GROUP BY,因此您不会将Receipt_DetailChargeSlip_Detail中的行相乘。也就是说,在加入Item_Number

之前,每Items生成一个SUM值
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)

答案 2 :(得分:0)

左连接从左表中返回行,对于左表中的每一行,返回右表中的所有匹配行。

例如:

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