2017-05-19 6 views
1

Ich habe Aufzeichnungen über Kundenanrufe mögen;Angekettete Aufzeichnungen - Zählung der Wiederholung der Aufzeichnungen

PHONENO  CALLTIME  REP 
======== =================== === 
01555444 10.03.2017 10:30:00 N <- first occurence of 01555444 
02888999 12.03.2017 11:40:20 N 
01555444 15.03.2017 18:22:33 Y <- repeated 1st time 01555444 
03666777 18.03.2017 20:36:44 N 
01555444 19.03.2017 08:15:47 Y <- repeated 2nd time 01555444 
01555444 30.03.2017 22:18:30 N <- first occurence of 01555444 (gap more than 10 days) 

Wenn ein Anruf innerhalb der nächsten 10 vom vorherigen Anruf occures (von derselben Telefonnummer), dann ist es einen wiederholter Anruf (zugeordnet ‚Y‘ in der Spalte REP) angenommen.

Jetzt möchte ich die Tabelle wie folgt mit der Anzahl der Wiederholungen haben:

PHONENO  CALLTIME  REP REPNO 
======== =================== === ===== 
01555444 10.03.2017 10:30:00 N 0 
02888999 12.03.2017 11:40:20 N 0 
01555444 15.03.2017 18:22:33 Y 1 
03666777 18.03.2017 20:36:44 N 0 
01555444 19.03.2017 08:15:47 Y 2 
01555444 30.03.2017 22:18:30 N 0 

REPNO stellt die Anzahl der (verkettet) Rufwiederholung (innerhalb von 10 Tagen).

Wie berechnet man das?

+1

'Mysql' oder' Oracle'? – Nitish

+0

Oracle bevorzugt – sbrbot

Antwort

0

Hier ist eine Art und Weise tun, die die tabibitosan Methode verwendet die Gruppen von wiederholten Zeilen zu identifizieren: durch erste

WITH cust_calls AS (SELECT '01555444' phoneno, to_date('10/03/2017 10:30:00', 'dd/mm/yyyy hh24:mi:ss') calltime FROM dual UNION ALL 
        SELECT '02888999' phoneno, to_date('12/03/2017 11:40:20', 'dd/mm/yyyy hh24:mi:ss') calltime FROM dual UNION ALL 
        SELECT '01555444' phoneno, to_date('15/03/2017 18:22:33', 'dd/mm/yyyy hh24:mi:ss') calltime FROM dual UNION ALL 
        SELECT '03666777' phoneno, to_date('18/03/2017 20:36:44', 'dd/mm/yyyy hh24:mi:ss') calltime FROM dual UNION ALL 
        SELECT '01555444' phoneno, to_date('19/03/2017 08:15:47', 'dd/mm/yyyy hh24:mi:ss') calltime FROM dual UNION ALL 
        SELECT '01555444' phoneno, to_date('30/03/2017 22:18:30', 'dd/mm/yyyy hh24:mi:ss') calltime FROM dual UNION ALL 
        SELECT '01555444' phoneno, to_date('30/04/2017 23:42:31', 'dd/mm/yyyy hh24:mi:ss') calltime FROM dual UNION ALL 
        SELECT '01555444' phoneno, to_date('05/05/2017 16:35:41', 'dd/mm/yyyy hh24:mi:ss') calltime FROM dual UNION ALL 
        SELECT '01555444' phoneno, to_date('20/05/2017 21:20:52', 'dd/mm/yyyy hh24:mi:ss') calltime FROM dual UNION ALL 
        SELECT '02888999' phoneno, to_date('12/03/2017 11:45:20', 'dd/mm/yyyy hh24:mi:ss') calltime FROM dual), 
    -- end of mimicking a table with your sample data in it. You do not need the above subquery, since you already have the table. 
    initial_info AS (SELECT phoneno, 
          calltime, 
          CASE WHEN calltime - LAG(calltime) OVER (PARTITION BY phoneno ORDER BY calltime) <= 10 THEN 'Y' ELSE 'N' END rep_row 
        FROM cust_calls), 
    middle_info AS (SELECT phoneno, 
          calltime, 
          rep_row rep, 
          CASE WHEN rep_row = 'Y' THEN 
            row_number() OVER (PARTITION BY phoneno ORDER BY calltime) 
             - row_number() OVER (PARTITION BY phoneno, rep_row ORDER BY calltime) 
          END rep_grp 
        FROM initial_info) 
SELECT phoneno, 
     calltime, 
     rep, 
     CASE WHEN rep_grp is not NULL THEN 
       row_number() OVER (PARTITION BY phoneno, rep_grp ORDER BY calltime) 
     END repno 
FROM middle_info 
ORDER BY phoneno, calltime; 

PHONENO CALLTIME   REP  REPNO 
-------- ------------------- --- ---------- 
01555444 05/05/2017 16:35:41 Y   1 
01555444 10/03/2017 10:30:00 N 
01555444 15/03/2017 18:22:33 Y   1 
01555444 19/03/2017 08:15:47 Y   2 
01555444 20/05/2017 21:20:52 N 
01555444 30/03/2017 22:18:30 N 
01555444 30/04/2017 23:42:31 N 
02888999 12/03/2017 11:40:20 N 
02888999 12/03/2017 11:45:20 Y   1 
03666777 18/03/2017 20:36:44 N 

Dies funktioniert die wiederholten Zeilen Identifizierung durch die aktuelle Zeile des Calltime mit der vorherige Reihe von Calltime zu vergleichen und entscheiden, ob es innerhalb von 10 Tagen ist oder nicht. Wenn Sie diese Informationen bereits haben, können Sie diesen Schritt überspringen und direkt zum nächsten gehen.

Als nächstes verwenden wir die Tabibitosan-Methode, um aufeinanderfolgende Zeilen über alle Zeilen für das gleiche phoneno und über alle Zeilen zu vergleichen, wobei rep_row 'Y' ist.

Dann können wir die Nummer aus dem vorherigen Schritt verwenden, um die Phoneno-Zeilen noch weiter zu partitionieren und dann die analytische Funktion row_number() darauf anzuwenden.

+0

Vielen Dank für dieses Know-how. Ich habe noch eine weitere Frage zu diesem Thema; ist es möglich, dass die Partition in 'PARTITION BY' aus mehr als einer Spalte besteht? Hier suche ich nach der gleichen Telefonnummer und das ist 'PARTITION BY phoneno'. In meinem Fall sind Kunden gleich, wenn "Phoneno ODER Assetid" zwischen ihnen gleich ist. So, wie man Partitionen definiert, in denen phoneno oder Anlagen das selbe sind? – sbrbot

+0

Es ist schwer, ohne weitere Beispieldaten von Ihnen zu sagen, die Ihr tatsächliches Szenario zeigen. Die Klausel "PARTITION BY" einer analytischen Funktion funktioniert jedoch genauso wie die Klausel "GROUP BY" in einer Aggregatabfrage. Wenn Sie angeben können, was eine Gruppe von Zeilen zu einer Gruppe macht, können Sie diese in der Klausel "PARTITION BY" verwenden. Vielleicht brauchen Sie in Ihrem Fall etwas wie "PARTITION BY phoneno, assetid" oder vielleicht eher "PARTITION BY COALESCE (phoneno, assetid)". – Boneist