SQL-Code: Letzte 7 Tage von bestimmte Zeitintervalt

Seven

Benutzer
Beiträge
5
Hallo Leute,

ich verzweifele hier gerade ein wenig:

Ich habe z.b. eine Tabelle mit: AnrufID, KundenID, Datum

Ich will jetzt alle KundenID´s die
- im Zeitraum 01.12.2017 - 31.01.2018 innerhalb von 5 Tagen mindestens 3x Angerufen haben.

D.h. am 01.12.2017 werden letzte 5 tage angeschaut, am 02.12 letzten 5 tage etc.

Ich will das ungern manuell per hand, für jeden Tag machen.

Kann mir da jemand helfen?
 
Werbung:
Also ich könnte mir sowas vorstellen:
Code:
SELECT   t.*
FROM   tabelle t
WHERE   t.Datum BETWEEN '2017-12-01' AND '2018-01-31'
AND   (   SELECT   count(*)
     FROM   tabelle
     WHERE   tabelle.KundenID = t.KundenID
     AND     datediff(day,tabelle.Datum,t.Datum) BETWEEN -5 AND 5 ) > 3
Ich bin mir aber nicht sicher ob MySQL den Zugriff auf die selbe Tabelle im Subselect so zuläßt oder ob man da tricksen muss. Außerdem musst du datediff() an MySQL anpassen und ich gehe mal davon aus das du jetzt eine DATE Spalte ohne Zeitanteil (also kein DATETIME oder so) nutzt.
 
Funktioniert leider nicht, zählt auch Einträge die nicht in den 5 tage Interval passen (habs überprüft).

Ich hätte an einer Schleife gedacht, wie bei Java, das z.b. 01.12 - 5 tage überprüft und in einer temp tabelle gespeichert und danach +1 Tag überprüft gespeichert etc.
 
Schleifen sind immer schlecht, egal welches SQL. Zeig mal ein paar Beispieldatensätze und das Query mit Ergebnis das du ausgeführt hast.
 
Beispiel Tabelle:

AnrufID - KundenID - AnrufsDatum
1 --------- A1 ---------- 01.01.2017
2 --------- A1 ---------- 01.01.2017
3 --------- A1 ---------- 02.01.2018
4 --------- A1 ---------- 03.01.2018
5 --------- A1 ---------- 04.01.2018
6 --------- A1 ---------- 05.01.2018
7 --------- A2 ---------- 06.01.2018
8 --------- A2 ---------- 08.01.2018
9 --------- A2 ---------- 11.01.2018
10 -------- A1 ---------- 25.01.2018

=
- AnrufID 1, 2 soll nicht gezählt werden, da es nicht in Betrachtungszeitraum steht
- AnrufID 3,4,5,6 = Innerhalb 5 Tagen mehr als 3x Anruf =
- AnrufID 7,8,9 ebenfalls innerhalb 5 tage mehr als 3x Anruf
- AnrufID 10 wird ignoriert, da nicht innerhalb 5 tage mehr als 3x Anruf

Dadurch sollte ausgegeben werden:

Anzahl_Anrufe - KundenID
3 ----------------- A1
3 ----------------- A2

Code:
SELECT   count(t1.anrufID), t1.call_kundenID
FROM   tabelle t1

WHERE   t1.Anrufsdatum BETWEEN '2017-12-01' AND '2018-01-31'

AND   (   SELECT  count(t2.anrufsId)
     FROM   tabelle t2
     WHERE   t2.call_anrufsID= t1.AnrufsID
     AND     datediff(day,t2.Anrufsdatum,t1.Anrufsdatum) BETWEEN -7 AND 0 ) > 3
 
Werbung:
Also du hast schonmal einen Fehler in deinem Select. Im Subselect setzt du Anruf(s)ID aus t1 mit der aus t2 gleich, das muss aber die KundenID sein. Daher liefert dein Select schonmal keine Daten weil natürlich jede AnrufID einmalig ist und nicht mehrfach vorkommt.

Code:
WITH tabelle(AnrufID,KundenID,AnrufsDatum) AS (
   SELECT 1,'A1',cast('2017-01-01' AS DATE) UNION ALL
   SELECT 2,'A1','2017-01-01' UNION ALL
   SELECT 3,'A1','2018-01-02' UNION ALL
   SELECT 4,'A1','2018-01-03' UNION ALL
   SELECT 5,'A1','2018-01-04' UNION ALL
   SELECT 6,'A1','2018-01-05' UNION ALL
   SELECT 7,'A2','2018-01-06' UNION ALL
   SELECT 8,'A2','2018-01-08' UNION ALL
   SELECT 9,'A2','2018-01-11' UNION ALL
   SELECT 10,'A1','2018-01-25'
   )
SELECT   *
FROM   tabelle t1
WHERE  t1.Anrufsdatum BETWEEN '2017-12-01' AND '2018-01-31'
AND   (   SELECT   count(t2.AnrufId)
     FROM   tabelle t2
     WHERE   t2.KundenID = t1.KundenID
     AND     datediff(day,t1.Anrufsdatum,t2.Anrufsdatum) BETWEEN -5 AND 5 ) >= 3

3 A1 2018-01-02
4 A1 2018-01-03
5 A1 2018-01-04
6 A1 2018-01-05
7 A2 2018-01-06
8 A2 2018-01-08
9 A2 2018-01-11

Dann macht mein Select auch erstmal keinen count(*) (da fehlt dann auch ein GROUP BY bei dir) denn: Es werden erstmal alle Datensätze aus der Tabelle geholt die in einem Zeitfenster von -X bis +Y Tagen mindestens 2 weitere Datensätze vom selben Kunden gefunden werden. Liegt also ein Anruf an Tag -5 einer an Tag 0, einer an Tag +5 wird der nur der Eintrag an Tag 0 ausgegeben. Denn Tag -5 und Tag 5 liegen zu weit auseinander. Das zu zählen ergibt keinen Sinn.

Man kann das auch zählen in dem man sich zu jedem Tag, auf den mindestens zwei Anrufe in kurzer Zeit folgen die Folgetage zählt. Gibt es dann aber 4 Anrufe wirst du einmal 4 Tage und einmal 3 zählen weil natürlich auch der zweite Tag noch zwei Folgetage in der Zeitspanne liegen hat. Vielleicht besser verständlich wenn man es mal ohne das Minimum von 3 Anrufen ausgibt:
Code:
WITH tabelle(AnrufID,KundenID,AnrufsDatum) AS (
   SELECT 1,'A1',cast('2017-01-01' AS DATE) UNION ALL
   SELECT 2,'A1','2017-01-01' UNION ALL
   SELECT 3,'A1','2018-01-02' UNION ALL
   SELECT 4,'A1','2018-01-03' UNION ALL
   SELECT 5,'A1','2018-01-04' UNION ALL
   SELECT 6,'A1','2018-01-05' UNION ALL
   SELECT 7,'A2','2018-01-06' UNION ALL
   SELECT 8,'A2','2018-01-08' UNION ALL
   SELECT 9,'A2','2018-01-11' UNION ALL
   SELECT 10,'A1','2018-01-25'
   )
SELECT   *,
     (   SELECT   count(t2.AnrufId)
       FROM   tabelle t2
       WHERE   t2.KundenID = t1.KundenID
       AND     datediff(day,t1.Anrufsdatum,t2.Anrufsdatum) BETWEEN 0 AND 5 ) - 1 AS anzahl_folgeanrufe_innerhalb_der_naechsten_5_tage
FROM   tabelle t1
WHERE  t1.Anrufsdatum BETWEEN '2017-12-01' AND '2018-01-31'
AnrufID KundenID AnrufsDatum anzahl_folgeanrufe_innerhalb_der_naechsten_5_tage
----------- -------- ----------- -------------------------------------------------
3 A1 2018-01-02 3
4 A1 2018-01-03 2
5 A1 2018-01-04 1
6 A1 2018-01-05 0
7 A2 2018-01-06 2
8 A2 2018-01-08 1
9 A2 2018-01-11 0
10 A1 2018-01-25 0

(8 Zeile(n) betroffen)
Es handelt sich jeweils um einen Anruf mit Datum und der Anzahl an Anrufen die ihm in den folgenden 5 Tagen vom selben Kunden folgen.

Das läßt sich jetzt aber nur schwer sinnvoll zusammen zählen, man muss genau wissen wie man was zählen will. Stellt man das jetzt etwas um und hat noch einen weiteren Anruf am 29.12.2017 von Kunde A1 ergibt sich folgendes Bild:
Code:
WITH tabelle(AnrufID,KundenID,AnrufsDatum) AS (
   SELECT 1,'A1',cast('2017-01-01' AS DATE) UNION ALL
   SELECT 11,'A1','2017-12-29' UNION ALL
   SELECT 2,'A1','2017-01-01' UNION ALL
   SELECT 3,'A1','2018-01-02' UNION ALL
   SELECT 4,'A1','2018-01-03' UNION ALL
   SELECT 5,'A1','2018-01-04' UNION ALL
   SELECT 6,'A1','2018-01-05' UNION ALL
   SELECT 7,'A2','2018-01-06' UNION ALL
   SELECT 8,'A2','2018-01-08' UNION ALL
   SELECT 9,'A2','2018-01-11' UNION ALL
   SELECT 10,'A1','2018-01-25'
   )
SELECT   *,
     (   SELECT   count(t2.AnrufId)
       FROM   tabelle t2
       WHERE   t2.KundenID = t1.KundenID
       AND     datediff(day,t1.Anrufsdatum,t2.Anrufsdatum) BETWEEN 0 AND 5 ) AS anzahl_anrufe_innerhalb_5_tage
FROM   tabelle t1
WHERE  t1.Anrufsdatum BETWEEN '2017-12-01' AND '2018-01-31'
AnrufID KundenID AnrufsDatum anzahl_anrufe_innerhalb_5_tage
----------- -------- ----------- ------------------------------
11 A1 2017-12-29 3
3 A1 2018-01-02 4
4 A1 2018-01-03 3
5 A1 2018-01-04 2
6 A1 2018-01-05 1
7 A2 2018-01-06 3
8 A2 2018-01-08 2
9 A2 2018-01-11 1
10 A1 2018-01-25 1

(9 Zeile(n) betroffen)
Jetzt hast du mehrere überlappende Zeitfenster in denen der Kunde A1 öfter angerufen hat. Zählst du da jedes Fenster einzeln? Dann passt die Summe der Anrufe nicht. Zählst du nur den Anfang eines Fensters und dann erst wieder los wenn 5 Tage um sind? Dann wäre der 29.12.2017 bis zum 03.01.2018 das erste Fenster, die Anrufe vom 04. und 05.01.2018 würden da aber nicht zugehören.
 
Zurück
Oben