2017-01-26 11 views
2

異なるテーブルの関連するデータを比較する際に問題が発生しましたので、以下のトピックについて少し助けていただきたいと思います。残念ながら、私はDBSが何であるか分かりませんが(何も最先端はありません)、IBMのハードウェア上で実行しています。基本的に請求額がでカバーされている場合 - 目的は2つのテーブルを比較し、一致があるかどうかを確認することですSQLの選択的グループ化

INVOICES

Doci   Sumi 
1005   10 
1006   15 
1007   7 
1008   20 

支払い

Docp  Sump 
1006   -15 
1005   -4 
1005   -6 
1007   -7 

:だからデータセットを簡単にするために、支払いの有無最初の新しいことは、他のチャートの負の値にある数値データを比較することでしたが、-1の乗数で動作するようにしました。

私が実際に解決策を思い付くことができない残りの問題は、本質的に、レコード/請求書なし1005が2つのトランザクションでカバーされていることをクエリに理解させることです。基本的に結果は支払いテーブルに一致するものがないため、請求書番号1008のみにする必要があります。

私はSQL集計関数、つまりSUMをレビューしましたが、Sump列全体の値を要約したくないのに、同じレコードを持つものだけを要約したくないということを実際には理解していませんでしたDocp列に入力します。これまでのところ私が持っているもの

はこれです:

SELECT * from INVOICES 
inner join PAYMENTS on INVOICES.Doci = PAYMENTS.Docp 
where Sumi <> (Sump*-1) 

ので、一見として、このクエリは、私は結果に、このような1006,1007などのレコードを取得することはできません限り動作しますが、私は1005を入手できますか値10は4 + 6の代わりに4と比較されます。

フィードバックには前もって感謝します!

+1

はそれについて考えるために来て、私はあなたの希望の結果に本当に明確ではありませんよ –

答えて

2

あなたはこれを試す

select i.* from invoices i 
inner join (
    select 
     docp, 
     sum(sump) sump 
    from payments 
    group by docp 
) p on i.doci = p.docp 
and i.sumi + p.sump <> 0 
0

各docpの総サンプを検索し、ドキュメントに基づいて請求書テーブルとそれに参加し、合計することができ、それはあなただけoustanding量を与えるだろう。

declare @inv table (Doci int, Sumi decimal) 
insert @inv values (1005, 10), (1006, 15), (1007, 7), (1008, 20) 

declare @pmt table (Docp int, Sump decimal) 
insert @pmt values (1005, -4), (1006, -15), (1007, -7), (1005, -6) 

;with payments(doc, amt) 
as (
    select Docp, sum(Sump) 
    from @pmt 
    group by Docp 
) 
select Doci, Sumi + isnull(amt,0) as Remaining 
from @inv 
left outer join payments p on p.doc = Doci 
where (Sumi + isnull(amt,0)) <> 0 

結果:

Doci  Remaining 
----------- ---------- 
1008  20 
0

私は2つの段階でこれをやりましたか? - 複数の支払いがあった場合は、それらが一緒に識別するためにグループにいた、そしてかどうかそれバランスの取れた請求書またはない:それは唯一の支払いがカバーするには不十分であった値を返しますよう

SELECT doci, sumi, docp, sum(sump) as Sump INTO #Step1 
from #INVOICES 
inner join PAYMENTS on INVOICES.Doci = PAYMENTS.Docp 
GROUP BY 
doci, sumi, docp 

GO 

SELECT * from INVOICES 
inner join #PAYMENTS on #INVOICES.Doci = #PAYMENTS.Docp 
where Sumi <> (Sump*-1) AND doci NOT IN (select doci from #step1 WHERE sumi+Sump = 0) 

結果は、空のデータセットです

第1の和によって支払い:あなたの例では、請求書(!またはあまり)

すべてのIDが一致する(つまり、支払請求書==)あなたがステップに問題を分割する必要が

0

を持っていますそれはid、Docpです。

select 
    Docp, 
    SUM(Sump) as payment_sum 
from PAYMENTS 
group by Docp 

このクエリの結果をPAYMENT_SUMとしましょう。

次に請求書と比較してください。

select 
    I.Doci, 
    I.sumi + P.payment_sum as diff 
from INVOICES I 
left join PAYMENT_SUM P 
on I.Doci = P.Docp 
; 

これは、あなたとその結果得られます:

Doci diff 
1005 0 
1006 0 
1007 0 
1008 null 

は今、この結果を見て、あなたが望むものを選択するために、クエリに1つのより多くの句を追加することができます。 お支払い側のまったく一致して請求書を選択したい場合は、また、支払いに試合を持っていますが、量が完全に覆われていないこれらの請求書を持っているしたい場合は、その句は、

where P.Docp is null 

であるか、またはなります、そして:

where (P.Docp is null) or ((I.sumi + P.payment_sum) <> 0) 

は今、すべてのステップを組み合わせること:

select 
     I.Doci, 
     I.sumi + P.payment_sum as diff 
    from INVOICES as I 
    left join (
     select 
      Docp, 
      SUM(Sump) as payment_sum 
     from PAYMENTS 
     group by Docp 
    ) as P 
    on I.Doci = P.Docp 

    where (P.Docp is null) or (I.sumi + P.payment_sum) <> 0 
    ; 
関連する問題