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

テーブルを結合しているため、を取得したときに問題を引き起こしている1対多の関係がある可能性がありますsum()。したがって、サブクエリを使用して結果を取得できます。これにより、sum()forreceiptとforeachが取得さchargeslipれ、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
于 2013-02-25T13:03:43.400 に答える
0

ごとに最初にGROUPBYを実行して、とからのItem_Number行を乗算しないようにします。つまり、JOINに戻る前にごとにSUM値を生成します。Receipt_DetailChargeSlip_DetailItem_NumberItems

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 に答える
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

ご覧のとおり、結合は互いに繰り返されることになります。製品ごとに、アドレスのリストが繰り返されます。それはあなたに間違ったカウントを与えます。この問題を解決するには、他の優れた回答の1つを使用してください。

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

サブクエリにより、顧客ごとに1つの行のみが結合されます。結果ははるかに優れています:

name    order_count address_count
Tim     1           1
John    2           2
Spike   NULL        NULL
于 2013-02-25T13:12:48.313 に答える