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

我的代码有什么问题?

4

3 回答 3

2

由于您要连接表,因此当您获得sum(). 因此,您可以使用子查询来获取结果。这将得到sum()for thereceiptchargeslipfor eachitem_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
于 2013-02-25T13:03:43.400 回答
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

但是 John 没有 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
于 2013-02-25T13:12:48.313 回答
0

首先执行 GROUP BY, per Item_Number,这样您就不会从Receipt_Detailand中乘出行ChargeSlip_Detail。也就是说,您Item_Number在 JOINing 之前生成 SUM 值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)
于 2013-02-25T13:03:58.270 回答