Benutzer mit den meisten Antworten
Abfrage von Kundenkonto auf Basis von Zahlungsverhalten

Frage
-
Hallo zusammen,
ich bin total neu in diesem Forum und hoffe jemand kann mir helfen.
Ich soll Kunden selektieren, die folgender Logik entsprechen:
Alle Kunden identifizieren, die...
a) deren Rückstand in den letzten 6 Monaten im Vergleich zum jeweiligen Vormonat nicht angestiegen ist und...
b) zum letzten Ultimo rückstandsfrei waren
Vereinfachtes Bsp.:
Die rot markierten Kunden 3495750016 und 3495750025 sollen selektiert werden.
Der grün markierte Kunde 3495750026 ist OK, da der Rückstand langsam abgebaut wurde und zum Ultimo (31.10.2012) auf 0,- war.
Die obige Tabelle ergibt sich aus folgender Abfrage:
SELECT Kunde , DATEH AS datum , (TILGRUE + ZINSRUECK + BUERGGEB+VERZZIN + DAMNUM+REFISCH + BEARBGEB + SONKOST + BEREITZI) AS RueckstandGesamt , row_number () over (partition by ranl order by DATEH asc) AS RN FROM DATA.tY1ADATAH WHERE DATEH > DATEADD(month, -6, getdate()) AND DATEH < getdate()
Da ich noch etwas neu in SQL bin habe ich bisher hierfür keine Lösung gefunden.
Kann mir jemand helfen?
Antworten
-
Hallo und guten Abend,
ungestestet:
zu a)
WITH Daten AS ( SELECT Kunde AS kunde , DATEH AS datum , (TILGRUE + ZINSRUECK + BUERGGEB+VERZZIN + DAMNUM+REFISCH + BEARBGEB + SONKOST + BEREITZI) AS RueckstandGesamt FROM DATA.tY1ADATAH ) , result AS ( SELECT d1.kunde, d1.datum AS datum_1, d2.datum AS datum_2, d1.RueckstandGesamt FROM Daten d1 LEFT JOIN Daten d2 ON (d1.kunde = d2.kunde) WHERE d1.datum < d2.datum AND d1.RueckstandGesamt = d2.RueckstandGesamt ) SELECT * FROM result
zu b)
WITH DATEN AS ( SELECT Kunde , DATEH AS datum , (TILGRUE + ZINSRUECK + BUERGGEB+VERZZIN + DAMNUM + REFISCH + BEARBGEB + SONKOST + BEREITZI) AS RueckstandGesamt , row_number () over (partition by ranl order by DATEN DESC) AS RN FROM DATA.tY1ADATAH ) SELECT * FROM daten WHERE RN = 1 AND RueckstandGesamt = 0
Schönen Abend.- Als Antwort markiert Daniel Del Monaco Mittwoch, 28. November 2012 14:21
-
Hallo Daniel,
sorry, das ich zunächst etwas unaufmerksam beim Lesen war.
Ich habe daraufhin das Script noch einmal angepasst.
Du findest am Ende die beiden Zeilen:
SELECT * FROM kunde_ok
SELECT * FROM result
Du kannst immer nur eine Abfrage ausführen (die andere auskommentieren).
SELECT * FROM result wird Dir die die Einzeldaten anzeigen; so kannst Du leicht etwaige Änderungswünsche selbst vornehmen.
USE tempdb GO SET NOCOUNT ON GO CREATE TABLE tbl_Forum( Kunde DECIMAL, Datum DATETIME, RueckstandGesamt MONEY ) GO INSERT INTO tbl_Forum (Kunde, Datum, RueckstandGesamt) SELECT 3495750016, '20120531', 540.57 UNION ALL SELECT 3495750016, '20120630', 39.47 UNION ALL SELECT 3495750016, '20120730', 15.24 UNION ALL SELECT 3495750016, '20120831', 18.47 UNION ALL SELECT 3495750016, '20120930', 533.59 UNION ALL SELECT 3495750016, '20121031', 0 UNION ALL SELECT 3495750025, '20120531', 138.17 UNION ALL SELECT 3495750025, '20120630', 0 UNION ALL SELECT 3495750025, '20120730', 0 UNION ALL SELECT 3495750025, '20120831', 0 UNION ALL SELECT 3495750025, '20120930', 137.09 UNION ALL SELECT 3495750025, '20121031', 0 UNION ALL SELECT 3495750026, '20120531', 150 UNION ALL SELECT 3495750026, '20120630', 130 UNION ALL SELECT 3495750026, '20120730', 110 UNION ALL SELECT 3495750026, '20120831', 90 UNION ALL SELECT 3495750026, '20120930', 70 UNION ALL SELECT 3495750026, '20121031', 0 GO WITH Daten AS ( SELECT Kunde , Datum , RueckstandGesamt FROM tbl_forum ) , result AS ( SELECT d1.kunde, d2.datum AS datum, d2.RueckstandGesamt AS RueckstandGesamt, d1.datum AS datum_vormonat, d1.RueckstandGesamt AS RueckstandGesamt_vormonat, CASE WHEN d1.RueckstandGesamt - d2.RueckstandGesamt >= 0 THEN 0 ELSE 1 END AS Tilgung FROM Daten d1 LEFT JOIN Daten d2 ON (d1.kunde = d2.kunde) WHERE d1.datum < d2.datum AND DATEDIFF (mm, d1.datum, d2.datum) = 1 AND DATEDIFF (mm, d1.datum, GETDATE ()) BETWEEN 0 AND 6 ) , kunde_ok AS ( SELECT kunde FROM result GROUP BY kunde HAVING SUM (Tilgung) = 0 ) SELECT * FROM kunde_ok --SELECT * FROM result GO DROP TABLE tbl_forum
Schönen Abend.
- Als Antwort markiert Daniel Del Monaco Donnerstag, 29. November 2012 15:01
-
Hallo Joerg_x,
vielen Dank für deine Antwort!! Sie hat mich auf die richtige fährte gebracht.
Meine Lösung sieht jetzt so aus:
WITH DATEN AS ( SELECT DISTINCT Kunde , Datum , (TILGRUE + ZINSRUECK + BUERGGEB+VERZZIN + DAMNUM+REFISCH + BEARBGEB + SONKOST + BEREITZI) AS RueckstandGesamt , row_number () over (partition by Kunde order by Datum asc) AS RN FROM DATA.tY1ADATAH WHERE Datum > DATEADD(month, -6, getdate()) AND Datum < getdate() /* nur die letzten 6 Monate betrachten*/ ) , RESULT AS ( SELECT DISTINCT DATEN1.Kunde AS DATEN1, DATEN2.Kunde AS DATEN2, DATEN1.datum AS DATUM1, DATEN2.datum AS DATUM2, DATEN1.RueckstandGesamt AS RueckstandGesamt1, DATEN2.RueckstandGesamt AS RueckstandGesamt2, DATEN1.RN AS RN1, DATEN2.RN AS RN2, CASE WHEN DATEN2.RueckstandGesamt <= DATEN1.RueckstandGesamt THEN 1 ELSE 0 END AS TEST /* zum Testen meiner Logik müssen alle Zeilen des Ergebnises 1 lauten*/ FROM DATEN DATEN1 LEFT JOIN DATEN DATEN2 ON DATEN1.Kunde = DATEN2.Kunde WHERE DATEN1.datum < DATEN2.datum AND DATEDIFF(month,DATEN1.datum,DATEN2.datum) = 1 /* nur den jeweils vorangegangenen Monat*/ AND (DATEN2.datum > DATEADD(month, -1, getdate()) AND DATEN2.RueckstandGesamt = 0) /* letzter Ultimo und Rückstand=0*/ ) SELECT DISTINCT * FROM RESULT
Ich habe soweit alles überprüft und kann sagen, dass alle unsere Kriterien so "gefangen" wurden. Auf jeden Fall wäre ich ohne deinen Ansatz nicht darauf gekommen!!! DANKE!!
- Als Antwort markiert Daniel Del Monaco Mittwoch, 28. November 2012 14:18
- Bearbeitet Daniel Del Monaco Mittwoch, 28. November 2012 14:24
Alle Antworten
-
Hallo und guten Abend,
ungestestet:
zu a)
WITH Daten AS ( SELECT Kunde AS kunde , DATEH AS datum , (TILGRUE + ZINSRUECK + BUERGGEB+VERZZIN + DAMNUM+REFISCH + BEARBGEB + SONKOST + BEREITZI) AS RueckstandGesamt FROM DATA.tY1ADATAH ) , result AS ( SELECT d1.kunde, d1.datum AS datum_1, d2.datum AS datum_2, d1.RueckstandGesamt FROM Daten d1 LEFT JOIN Daten d2 ON (d1.kunde = d2.kunde) WHERE d1.datum < d2.datum AND d1.RueckstandGesamt = d2.RueckstandGesamt ) SELECT * FROM result
zu b)
WITH DATEN AS ( SELECT Kunde , DATEH AS datum , (TILGRUE + ZINSRUECK + BUERGGEB+VERZZIN + DAMNUM + REFISCH + BEARBGEB + SONKOST + BEREITZI) AS RueckstandGesamt , row_number () over (partition by ranl order by DATEN DESC) AS RN FROM DATA.tY1ADATAH ) SELECT * FROM daten WHERE RN = 1 AND RueckstandGesamt = 0
Schönen Abend.- Als Antwort markiert Daniel Del Monaco Mittwoch, 28. November 2012 14:21
-
Hallo und guten Abend,
ungestestet:
zu a)
WITH Daten AS ( SELECT Kunde AS kunde , DATEH AS datum , (TILGRUE + ZINSRUECK + BUERGGEB+VERZZIN + DAMNUM+REFISCH + BEARBGEB + SONKOST + BEREITZI) AS RueckstandGesamt FROM DATA.tY1ADATAH ) , result AS ( SELECT d1.kunde, d1.datum AS datum_1, d2.datum AS datum_2, d1.RueckstandGesamt FROM Daten d1 LEFT JOIN Daten d2 ON (d1.kunde = d2.kunde) WHERE d1.datum < d2.datum AND d1.RueckstandGesamt = d2.RueckstandGesamt ) SELECT * FROM result
zu b)
WITH DATEN AS ( SELECT Kunde , DATEH AS datum , (TILGRUE + ZINSRUECK + BUERGGEB+VERZZIN + DAMNUM + REFISCH + BEARBGEB + SONKOST + BEREITZI) AS RueckstandGesamt , row_number () over (partition by ranl order by DATEN DESC) AS RN FROM DATA.tY1ADATAH ) SELECT * FROM daten WHERE RN = 1 AND RueckstandGesamt = 0
Schönen Abend.
Hallo Joerg_x,
vielen Dank für die schnelle Antwort. Ich habe deinen Ansatz jetzt mal ausprobiert. Leider passt es aber noch nicht.
Hier meine Gedanken:
Ich muss nur die letzten 6 Monate betrachten. Dein Lösungsansatz vergleicht alle vorhandenen Monate miteinander. Darüberhinaus, wird d1_Datum (1) mit allen d2_Datum (n) verglichen, also nicht nur mit dem jeweils vorangegangenen. Zum Beispiel, 31.05.2012 mit jeweils den d2_Datum 30.06.202 - 31.10.2012. Auch verstehe ich nicht, warum du in der Where-Klausel mit
d1.RueckstandGesamt = d2.RueckstandGesamt
einschränkst. Ich hätte erwartet man schränkt ein mit "kleiner od. gleich"
d1.RueckstandGesamt <= d2.RueckstandGesamt
Vielleicht sollte ich versuchen mich noch klarer auszudrücken:
Es geht darum die Kunden (Kreditnehmer) zu selektieren, deren Zahlungsverhalten in den letzten 6 Monaten darauf schliessen lässt, dass zukünftig der Zahlungsverzug unwahrscheinlich scheint. Wir definieren das hier so, dass in den letzten 6 Monaten der Zahlungsrückstand im Vergleich zum jeweiligen Vormonat nicht angestiegen ist (kann aber gleich bleiben) und zum letzten Ultimo kein Zahlungstückstand bestand. So stellen wir sicher, dass in den letzten 6 Monaten die vereinbarte Rate bezahlt wurde und der Zahlungsrückstand ausgeglichen wurde.
-
Hallo Joerg_x,
vielen Dank für deine Antwort!! Sie hat mich auf die richtige fährte gebracht.
Meine Lösung sieht jetzt so aus:
WITH DATEN AS ( SELECT DISTINCT Kunde , Datum , (TILGRUE + ZINSRUECK + BUERGGEB+VERZZIN + DAMNUM+REFISCH + BEARBGEB + SONKOST + BEREITZI) AS RueckstandGesamt , row_number () over (partition by Kunde order by Datum asc) AS RN FROM DATA.tY1ADATAH WHERE Datum > DATEADD(month, -6, getdate()) AND Datum < getdate() /* nur die letzten 6 Monate betrachten*/ ) , RESULT AS ( SELECT DISTINCT DATEN1.Kunde AS DATEN1, DATEN2.Kunde AS DATEN2, DATEN1.datum AS DATUM1, DATEN2.datum AS DATUM2, DATEN1.RueckstandGesamt AS RueckstandGesamt1, DATEN2.RueckstandGesamt AS RueckstandGesamt2, DATEN1.RN AS RN1, DATEN2.RN AS RN2, CASE WHEN DATEN2.RueckstandGesamt <= DATEN1.RueckstandGesamt THEN 1 ELSE 0 END AS TEST /* zum Testen meiner Logik müssen alle Zeilen des Ergebnises 1 lauten*/ FROM DATEN DATEN1 LEFT JOIN DATEN DATEN2 ON DATEN1.Kunde = DATEN2.Kunde WHERE DATEN1.datum < DATEN2.datum AND DATEDIFF(month,DATEN1.datum,DATEN2.datum) = 1 /* nur den jeweils vorangegangenen Monat*/ AND (DATEN2.datum > DATEADD(month, -1, getdate()) AND DATEN2.RueckstandGesamt = 0) /* letzter Ultimo und Rückstand=0*/ ) SELECT DISTINCT * FROM RESULT
Ich habe soweit alles überprüft und kann sagen, dass alle unsere Kriterien so "gefangen" wurden. Auf jeden Fall wäre ich ohne deinen Ansatz nicht darauf gekommen!!! DANKE!!
- Als Antwort markiert Daniel Del Monaco Mittwoch, 28. November 2012 14:18
- Bearbeitet Daniel Del Monaco Mittwoch, 28. November 2012 14:24
-
Hallo Daniel,
sorry, das ich zunächst etwas unaufmerksam beim Lesen war.
Ich habe daraufhin das Script noch einmal angepasst.
Du findest am Ende die beiden Zeilen:
SELECT * FROM kunde_ok
SELECT * FROM result
Du kannst immer nur eine Abfrage ausführen (die andere auskommentieren).
SELECT * FROM result wird Dir die die Einzeldaten anzeigen; so kannst Du leicht etwaige Änderungswünsche selbst vornehmen.
USE tempdb GO SET NOCOUNT ON GO CREATE TABLE tbl_Forum( Kunde DECIMAL, Datum DATETIME, RueckstandGesamt MONEY ) GO INSERT INTO tbl_Forum (Kunde, Datum, RueckstandGesamt) SELECT 3495750016, '20120531', 540.57 UNION ALL SELECT 3495750016, '20120630', 39.47 UNION ALL SELECT 3495750016, '20120730', 15.24 UNION ALL SELECT 3495750016, '20120831', 18.47 UNION ALL SELECT 3495750016, '20120930', 533.59 UNION ALL SELECT 3495750016, '20121031', 0 UNION ALL SELECT 3495750025, '20120531', 138.17 UNION ALL SELECT 3495750025, '20120630', 0 UNION ALL SELECT 3495750025, '20120730', 0 UNION ALL SELECT 3495750025, '20120831', 0 UNION ALL SELECT 3495750025, '20120930', 137.09 UNION ALL SELECT 3495750025, '20121031', 0 UNION ALL SELECT 3495750026, '20120531', 150 UNION ALL SELECT 3495750026, '20120630', 130 UNION ALL SELECT 3495750026, '20120730', 110 UNION ALL SELECT 3495750026, '20120831', 90 UNION ALL SELECT 3495750026, '20120930', 70 UNION ALL SELECT 3495750026, '20121031', 0 GO WITH Daten AS ( SELECT Kunde , Datum , RueckstandGesamt FROM tbl_forum ) , result AS ( SELECT d1.kunde, d2.datum AS datum, d2.RueckstandGesamt AS RueckstandGesamt, d1.datum AS datum_vormonat, d1.RueckstandGesamt AS RueckstandGesamt_vormonat, CASE WHEN d1.RueckstandGesamt - d2.RueckstandGesamt >= 0 THEN 0 ELSE 1 END AS Tilgung FROM Daten d1 LEFT JOIN Daten d2 ON (d1.kunde = d2.kunde) WHERE d1.datum < d2.datum AND DATEDIFF (mm, d1.datum, d2.datum) = 1 AND DATEDIFF (mm, d1.datum, GETDATE ()) BETWEEN 0 AND 6 ) , kunde_ok AS ( SELECT kunde FROM result GROUP BY kunde HAVING SUM (Tilgung) = 0 ) SELECT * FROM kunde_ok --SELECT * FROM result GO DROP TABLE tbl_forum
Schönen Abend.
- Als Antwort markiert Daniel Del Monaco Donnerstag, 29. November 2012 15:01
-
Hallo Daniel,
stimmt.
Hallo Joerg_x,
jetzt war ich aber etwas unaufmerksam ;-)
Wir haben beide die Einschränkung vergessen, dass zum Ultimo natürlich der Rückstand = 0 sein muss!!
Hast du vielleicht eine Idee, wie man das auch noch einbauen kann?
Ich hoffe jetzt passt es. Die Logik ist wie gehabt; dort wo bei check '0' steht, sind die Vorgaben erfüllt.
USE tempdb GO SET NOCOUNT ON GO CREATE TABLE tbl_Forum( Kunde DECIMAL, Datum DATETIME, RueckstandGesamt MONEY ) GO INSERT INTO tbl_Forum (Kunde, Datum, RueckstandGesamt) SELECT 3495750016, '20120531', 540.57 UNION ALL SELECT 3495750016, '20120630', 39.47 UNION ALL SELECT 3495750016, '20120730', 15.24 UNION ALL SELECT 3495750016, '20120831', 18.47 UNION ALL SELECT 3495750016, '20120930', 533.59 UNION ALL SELECT 3495750016, '20121031', 0 UNION ALL SELECT 3495750025, '20120531', 138.17 UNION ALL SELECT 3495750025, '20120630', 0 UNION ALL SELECT 3495750025, '20120730', 0 UNION ALL SELECT 3495750025, '20120831', 0 UNION ALL SELECT 3495750025, '20120930', 137.09 UNION ALL SELECT 3495750025, '20121031', 0 UNION ALL SELECT 3495750026, '20120531', 150 UNION ALL SELECT 3495750026, '20120630', 130 UNION ALL SELECT 3495750026, '20120730', 110 UNION ALL SELECT 3495750026, '20120831', 90 UNION ALL SELECT 3495750026, '20120930', 70 UNION ALL SELECT 3495750026, '20121031', 0 GO WITH Daten AS ( SELECT Kunde , Datum , RueckstandGesamt FROM tbl_forum ) , result AS ( SELECT d1.kunde, d2.datum AS datum, d2.RueckstandGesamt AS RueckstandGesamt, d1.datum AS datum_vormonat, d1.RueckstandGesamt AS RueckstandGesamt_vormonat, CASE WHEN d1.RueckstandGesamt - d2.RueckstandGesamt >= 0 THEN 0 ELSE 1 END AS Tilgung_Check, CASE WHEN DATEDIFF (mm, d2.datum, GETDATE ()) = 0 AND d2.RueckstandGesamt = 0 THEN 0 ELSE CASE WHEN DATEDIFF (mm, d2.datum, GETDATE ()) > 0 THEN 0 ELSE 1 END END AS Ultimo_check FROM Daten d1 LEFT JOIN Daten d2 ON (d1.kunde = d2.kunde) WHERE d1.datum < d2.datum AND DATEDIFF (mm, d1.datum, d2.datum) = 1 AND DATEDIFF (mm, d1.datum, GETDATE ()) BETWEEN 0 AND 6 ) , kunde_ok AS ( SELECT kunde FROM result GROUP BY kunde HAVING SUM (Tilgung_check) = 0 AND SUM (Ultimo_check) = 0 ) --SELECT * FROM kunde_ok SELECT * FROM result GO DROP TABLE tbl_forum
Schönen Abend.