2017-11-29 1 views
0

Ich habe ein PHP-Skript im Taskplaner jeden Tag von 7:45 bis 05.00 Uhr ausgeführt. Es funktioniert gut, aber für den ersten Lauf gibt es nichts zurück, da noch keine Datensätze erstellt wurden (Datensätze werden von CSR-Agenten erstellt, die Anrufe entgegennehmen). Ich habe die SQL-Abfragen im Skript ausgeführt, um Werte auszuwählen, zu aggregieren und in eine Tabelle einzufügen, und ich erstelle dann eine JSON-Datei aus diesen Werten. Auch das alles ist perfekt, außer dem ersten Lauf.Einfügen von 0 für leere Rückkehr bei Auswahl (SQL-Skript läuft auf Task-Scheduler)

Ich wurde gefragt, ob ich etwas hinzufügen kann, so dass, wenn dieser erste Job nichts zurückgibt, es nur 0 für alles einfügen würde. Auf diese Weise würden, selbst wenn es 5 Mal ohne Datensätze/Aufrufe im System lief, immer noch Daten vorhanden sein und die CSR-Bildschirme würden etwas anzeigen. Gibt es einen ziemlich einfachen Weg, dies zu tun?

Hier ist der Großteil des Skripts:

$data = mysqli_query($conn2, 
     "SELECT 
      case 
      when callingpartyno  in (select extension from test.test_users) 
      then callingpartyno 
      when finallycalledpartyno in (select extension from test.test_users) 
      then finallycalledpartyno 
      end as extension 
      , sum(duration) as total_talk_time_seconds 
      , round(sum(duration)/60,2) as total_talk_time_minutes 
      , sum(if(legtype1 = 1,1,0)) as total_outbound 
      , sum(case when(legtype1 = 1 and duration > 60) then 1 else 0 end) as credit_for_outbound 
      , sum(if(legtype1 = 2,1,0) and answered = 1) as total_inbound 
      , sum(if(legtype1 = 2,1,0) and answered = 0) as total_missed 
      , sum(if(legtype1 = 1, 1, 0)) +     -- outbound calls 
      sum(if(legtype1 = 2, 1, 0)) as total_calls 
      ,round((sum(if(legtype1 = 2,1,0) and answered = 1))/(sum(if(legtype1 = 1, 1, 0)) +     -- outbound calls 
      sum(if(legtype1 = 2, 1, 0))) * 100,2) as percent_answered 
      , now() as time_of_report 
      , curdate() as date_of_report 
     FROM 
      test.session a 
      join test.callsummary b 
      on a.notablecallid = b.notablecallid 
      where 
      date(a.ts) >= curdate() 
      and (
      callingpartyno in (select extension from test.test_users 
      ) 
      or finallycalledpartyno in (select extension from test.test_users 
      ) 
      ) 
      group by 
      extension") or die(mysqli_error($conn2)); 


    $stmt = mysqli_prepare($conn2, 
     "INSERT into test.test_totals 
       (extension, 
       total_talk_time_seconds, 
       total_talk_time_minutes, 
       total_outbound, 
       credit_for_outbound, 
       total_inbound, 
       missed_calls, 
       total_calls, 
       percent_answered, 
       date_of_report, 
        time_of_report) 
     VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 
     ON duplicate key 
     update 
       total_talk_time_seconds = values(total_talk_time_seconds), 
       total_talk_time_minutes = values(total_talk_time_minutes), 
       total_inbound = values(total_inbound), 
       total_outbound = values(total_outbound), 
       credit_for_outbound = values(credit_for_outbound), 
       missed_calls = values(missed_calls), 
       total_calls = values(total_calls), 
       percent_answered = values(percent_answered), 
       time_of_report = NOW()") or die(mysqli_error($conn2)); 

Antwort

1

Das Problem, denn manchmal kommt es Null Verlängerung Zeilen (keine Anrufe, keine Erweiterungen, keine Ergebnisse) sind

so das jetzt ändern query() die Sie in Ihrer Auswahl verwenden stammt aus einer einfachen Unterabfrage, und links verbinden Sie den Rest Ihrer Daten mit einer ON-Klausel, die immer wahr ist

Siehe http://sqlfiddle.com/#!9/9b2a1/6 für ein Beispiel - die Unterabfrage, die Pseudotabelle t entsteht immer ret urn eine Reihe. Wenn die Unterabfrage von Tabelle 1 eine oder mehrere Zeilen zurückgibt, werden die Zeilen t einfach identisch wiederholt. Wenn die Unteranfrage von Table1 null Zeilen zurückgibt, wird die Abfrage als Ganzes immer noch eine Zeile haben. Diese Abfrage kann niemals null Zeilen zurückgeben. Es ist das, was Sie mit Ihrer Abfrage tun müssen, um sicherzustellen, dass, selbst wenn Ihre tatsächlichen Datentabellen für einen bestimmten Zeitraum keine Zeilen enthalten, die gesamte Abfrage eine Zeile zurückgibt (mit einer Null-Erweiterung; Sie können sie bei Bedarf zu einem Wert zusammenfügen).

Edit:

In Bezug auf Ihre Frage, wäre es in etwa so aussehen:

SELECT 
    case 
    when YOUR_SUBQUERY.callingpartyno in (select extension from test.test_users) then YOUR_SUBQUERY.callingpartyno 
    when YOUR_SUBQUERY.finallycalledpartyno in (select extension from test.test_users) then YOUR_SUBQUERY.finallycalledpartyno 
    end as extension 
    , sum(YOUR_SUBQUERY.duration) as total_talk_time_seconds 
    , round(sum(YOUR_SUBQUERY.duration)/60,2) as total_talk_time_minutes 
    , sum(if(YOUR_SUBQUERY.legtype1 = 1,1,0)) as total_outbound 
    , sum(case when(YOUR_SUBQUERY.legtype1 = 1 and duration > 60) then 1 else 0 end) as credit_for_outbound 
    , sum(if(YOUR_SUBQUERY.legtype1 = 2,1,0) and YOUR_SUBQUERY.answered = 1) as total_inbound 
    , sum(if(YOUR_SUBQUERY.legtype1 = 2,1,0) and YOUR_SUBQUERY.answered = 0) as total_missed 
    , sum(if(YOUR_SUBQUERY.legtype1 = 1, 1, 0)) +     -- outbound calls 
    sum(if(YOUR_SUBQUERY.legtype1 = 2, 1, 0)) as total_calls 
    , round((sum(if(YOUR_SUBQUERY.legtype1 = 2,1,0) and YOUR_SUBQUERY.answered = 1))/(sum(if(YOUR_SUBQUERY.legtype1 = 1, 1, 0)) +     -- outbound calls 
    sum(if(YOUR_SUBQUERY.legtype1 = 2, 1, 0))) * 100,2) as percent_answered 
    , TIME_OF_REPORT 
    , DATE_OF_REPORT 
FROM 
    (SELECT NOW() AS TIME_OF_REPORT, CURDATE() AS DATE_OF_REPORT) T 
    LEFT OUTER JOIN 
    (
     SELECT * FROM 
     test.session a 
     join test.callsummary b 
      on a.notablecallid = b.notablecallid 
     where 
      date(a.ts) >= curdate() and 
      (
      callingpartyno in (select extension from test.test_users) 
      or 
      finallycalledpartyno in (select extension from test.test_users) 
     ) 
) YOUR_SUBQUERY 
    ON 1=1 
    group by 
    DATE_OF_REPORT, TIME_OF_REPORT, extension 

Ihre sQL ist im wesentlichen Klein. Ich habe die Bits in Großbuchstaben hinzugefügt. Ich kann das nicht testen, da ich nichts von Ihrer Tabellenstruktur und den Beispieldaten weiß. Daher kann ein Debuggen von Ihnen erforderlich sein, aber im Wesentlichen sollte (SELECT NOW() AS TIME_OF_REPORT, CURDATE() AS DATE_OF_REPORT) T immer eine Zeile zurückgeben. Die YOUR_SUBQUERY kann 0 bis N Zeilen zurückgeben. Im Fall von 0 Zeilen von YOUR_SUBQUERY sollte der Gesamtbericht immer noch 1 Zeile mit einer Uhrzeit (eigentlich zwei) zurückgeben, obwohl ich nicht sicher bin, warum Sie NOW() verwenden, was eine Uhrzeit und ein Datum sowie CURDATE () - das Quark scheint redundant zu sein, da es nur Informationen gibt, die bereits von NOW() gegeben wurden, aber ich habe es verlassen) und eine Null-Erweiterung. Alle Summen sollten 0 sein, obwohl ich nicht sicher bin, ob z.B. Die IF-Funktion von MySQL gibt, wenn sie wie IF(something_that_is_null = 2, 1, 0) ausgeführt wird, eine Null zurück (sie sollte nicht, der Test sollte zu der 0 falsch sein, sollte zurückgegeben und als 0 summiert werden). Wenn Sie bei der ersten Ausführung feststellen, dass alle Werte Null sind und nicht 0, können Sie COALESCE (logic_doing_sum_here, 0) verwenden, um sie von Null auf 0 zu setzen. Wenn Ihnen die Null-Erweiterung lästig ist, verwenden Sie COALESCE Standardwert

+0

Entschuldigung, ich denke, ich verstehe, wenn ich diese Geige betrachte, aber wie müsste ich meine bestehende Abfrage genau ändern? Meine now() ist eine von vielen Variablen in der Auswahl, also würde ich sie einfach in eine Unterabfrage einfügen? –

+0

ziemlich viel, ich werde die Frage bearbeiten, um ein bisschen mroe info zu geben (schrieb die Antwort von einem iphone und es ist ein richtiger Schmerz in den Arsch Kopieren und Einfügen von Code auf einem i –

+0

Ah, danke! Das macht Sinn, ich war einfach nicht sicher, wie man es richtig bearbeitet. –

Verwandte Themen