none
Abfrage von Kundenkonto auf Basis von Zahlungsverhalten RRS feed

  • 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?


    Dienstag, 27. November 2012 16:21

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.
    Dienstag, 27. November 2012 18:45
  • 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.

    Mittwoch, 28. November 2012 20:05
  • 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!!


    Mittwoch, 28. November 2012 14:14

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.
    Dienstag, 27. November 2012 18:45
  • 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.

    Mittwoch, 28. November 2012 11: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!!


    Mittwoch, 28. November 2012 14:14
  • 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.

    Mittwoch, 28. November 2012 20:05
  • Hallo Joerg_x,

    vielen Dank!!

    Deine Lösung ist eleganter als meine und die Aufbereitung ist einfach SPITZE!

    Donnerstag, 29. November 2012 15:04
  • 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?

    Freitag, 30. November 2012 17:39
  • 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.

    Freitag, 30. November 2012 22:12