2017-01-26 3 views
2

Ich habe Probleme, die zugehörigen Daten in verschiedenen Tabellen zu vergleichen. Ich wäre sehr dankbar, wenn Sie Hilfe zum unten stehenden Thema erhalten. Leider bin ich mir nicht sicher, was das DBS ist (nichts Schnittriges), aber es läuft auf IBM Hardware. So vereinfacht den Datensatz:SQL selective grouping

RECHNUNGEN

Doci   Sumi 
1005   10 
1006   15 
1007   7 
1008   20 

ZAHLUNGEN

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

Ziel zwei Tabellen zu vergleichen und sehen, ob es eine Übereinstimmung gibt - im Wesentlichen, wenn der Rechnungsbetrag abgedeckt wurde in die Zahlungen oder nicht. Die erste neue Sache für mich war, die numerischen Daten zu vergleichen, die in dem anderen Diagramm negative Werte haben, aber es mit dem -1-Multiplikator arbeiten zu lassen.

Das verbleibende Problem, für das ich nicht wirklich eine Lösung finden kann, besteht im Wesentlichen darin, die Abfrage zu verstehen, dass Datensatz/Rechnung Nr. 1005 abgedeckt ist, nur mit zwei Transaktionen. Im Wesentlichen sollte das Ergebnis nur Rechnungsnummer 1008 sein, da es in der Zahlungstabelle keine Übereinstimmung gibt.

Ich habe am Ende Überprüfung SQL-Aggregatfunktionen und nämlich SUM, aber wirklich nicht herausfinden, wie man es verwenden, da ich nicht Werte in der gesamten Sump-Spalte zusammenfassen möchte, sondern nur diejenigen, die eine identische Aufzeichnung haben in der Docp-Spalte.

Bisher, was ich habe, ist dies:

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

Also, diese Abfrage in dem Maße funktioniert, dass ich Aufzeichnungen nicht wie 1006 und 1007 im Ergebnis bekommen, aber ich 1005 bekommen, als scheinbar Wert 10 wird mit 4 anstelle von 4 + 6 verglichen.

Vielen Dank im Voraus für jede Rückmeldung!

+1

darüber nachdenken Komm, ich bin wirklich nicht klar, auf die gewünschten Ergebnisse –

Antwort

2

Sie insgesamt Sumpf jeden DOCP finden und es dann mit der Tabelle auf doc basierten Rechnungen beitreten und

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

versuchen diese Summe, wird es Ihnen nur oustanding Menge geben.

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 

Ergebnis:

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

ich diese Schritte in zwei tat? - hatten sie zusammen zu einer Gruppe zu identifizieren, wenn mehrere Zahlungen sind, und ob es ausgewogen Rechnung oder nicht:

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) 

Ergebnisse sind ein leerer Datensatz, wie es nur die Werte zurück, wo die Zahlung nicht ausreicht, die zur Deckung Rechnung (! oder zu viel)

Alle IDs in Ihrem Beispiel haben eine Übereinstimmung (dh Zahlungen == Rechnung)

0

Sie müssen das Problem in einzelne Schritte brechen:

Erste Summe der Zahlungen es ist id, Docp.

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

nennen wir das Ergebnis dieser Abfrage, PAYMENT_SUM.

Dann vergleichen Sie es mit Rechnung.

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

Dies wird Ihnen ein Ergebnis wie:

Doci diff 
1005 0 
1006 0 
1007 0 
1008 null 

nun an diesem Ergebnis suchen, können Sie eine weitere Klausel der Abfrage hinzufügen können wählen, was Sie wollen. Wenn Sie ohne Spiel überhaupt auf die Zahlung Seite auswählen Rechnung möchten, dann Klausel

where P.Docp is null 

Oder, wenn Sie wollen, auch solche Rechnungen haben, die ein Spiel in Zahlung hat aber die Menge nicht vollständig abgedeckt wird , dann gilt:

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

nun alle Schritte zu kombinieren:

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 
    ;