2016-05-14 6 views
0

Ich habe Schwierigkeiten mit der Bestimmung des MySQL-Codes, um eine Spalte (durchschnittlicher park_factor) in meiner Tabelle "starting_pitcher_stats" zu erstellen. Ich möchte gerne die jahreszeitlichen Durchschnittswerte der Werte in einer anderen Spalte (park_factor) enthalten. Ich würde mir wünschen, dass dieser Durchschnitt in der Saison nach Werfer und Datum gruppiert wird.Ich versuche, Spalte mit jahreszeitlichen Durchschnittswerten von Werten einer anderen Spalte in der gleichen Tabelle mit MySQL zu erstellen

Idealerweise würde die Tabelle wie folgt aussehen:

pitcher  park_fac avg_park_fac  date 
    aased001 94   94   1977-07-31 
    aased001 100  97   1977-08-06 
    aased001 108  100.666  1977-08-11 
    aased001 108  102.5  1977-08-16 
    aased001 96   101.2  1977-08-21 
    aased001 108  102.33  1977-08-26 
    aased001 108  103.14  1977-08-31 
    aased001 104  103.25  1977-09-05 
    aased001 108  103.77  1977-09-10 
    aased001 92   102.6  1977-09-16 
    aased001 106  102.9  1977-09-22 
    aased001 108  103.33  1977-09-27 

Der Code Ich verwende ist:

SELECT Starting_Pitcher, full_park_factor, AVG(full_park_factor), Game_Date 
FROM starting_pitcher_stats 
GROUP BY Starting_Pitcher, Game_Date, Game_Number 

... und eine Probe der resultierenden Tabelle sieht wie folgt aus:

pitcher  park_fac avg_park_fac date 
aased001 94   94.0000  1977-07-31 
aased001 100  100.0000  1977-08-06 
aased001 108  108.0000  1977-08-11 
aased001 108  108.0000  1977-08-16 
aased001 96   96.0000  1977-08-21 
aased001 108  108.0000  1977-08-26 
aased001 108  108.0000  1977-08-31 
aased001 104  104.0000  1977-09-05 
aased001 108  108.0000  1977-09-10 
aased001 92   92.0000  1977-09-16 
aased001 106  106.0000  1977-09-22 
aased001 108  108.0000  1977-09-27 

Kann jemand bitte helfen?

Vielen Dank im Voraus für Hilfe mit diesem. Lee

+1

Ich weiß nicht, was Sie wollen, dass wir Ihnen helfen. Erwägen Sie, korrekte CREATE- und INSERT-Anweisungen zu liefern, die dem gewünschten Ergebnis entsprechen. – Strawberry

+0

Hi strawberry, ich möchte nur eine Spalte avg_Park_factor erstellen, die den Durchschnittswert des entsprechenden Zeilenwerts + Werte von Zeilen von den vorherigen Daten innerhalb eines bestimmten Jahres enthält Spalte park_factors. – LeeZee

Antwort

2

Sie müssen Ihre Tabelle auf alle vorherigen Ergebnisse für den gleichen Krug aus der gleichen Tabelle beitreten.

Ich bin mir nicht ganz sicher, wie Sie Ihre Saison definieren, aber unter der Annahme, dass es sich um das Kalenderjahr handelt, erzeugt die folgende Abfrage die gewünschte Ausgabe.

SELECT 
    a.Starting_Pitcher, a.full_park_factor, 
    AVG(b.full_park_factor), a.Game_Date, a.Game_Number 
FROM starting_pitcher_stats a 
INNER JOIN starting_pitcher_stats b 
    ON a.Starting_Pitcher = b.Starting_Pitcher 
    AND (b.Game_Date < a.Game_Date OR 
     (b.Game_Date = a.Game_Date AND b.Game_Number <= a.Game_Number)) 
    AND YEAR(b.Game_Date) = YEAR(a.Game_Date) 
GROUP BY a.Starting_Pitcher, a.Game_Date, a.Game_Number; 

Sie scheinen eine Spalte in Ihrer Tabelle mit dem Ergebnis dieser Berechnung zu aktualisieren. Dies kann durch Echtzeit-Updates mit einem Trigger erreicht werden, der die Spalte aktualisiert, wenn Sie vorhandene Daten einfügen oder aktualisieren oder eine Ansicht verwenden.

CREATE VIEW starting_pitcher_stats_with_average AS 
SELECT 
    a.Starting_Pitcher, a.full_park_factor, 
    AVG(b.full_park_factor), a.Game_Date, a.Game_Number 
FROM starting_pitcher_stats a 
INNER JOIN starting_pitcher_stats b 
    ON a.Starting_Pitcher = b.Starting_Pitcher 
    AND (b.Game_Date < a.Game_Date OR 
     (b.Game_Date = a.Game_Date AND b.Game_Number <= a.Game_Number)) 
    AND YEAR(b.Game_Date) = YEAR(a.Game_Date) 
GROUP BY a.Starting_Pitcher, a.Game_Date, a.Game_Number; 

In Ihrer eigenen Antwort erstellen Sie eine Prozedur, die mittlere Spalte für alle Datensätze in der Tabelle auf einmal zu aktualisieren, vielleicht mögen Sie nicht die Spalte Update haben, wie Sie Daten einfügen, sondern einfach sein Kann den Durchschnitt für alle Zeilen bei Bedarf hinzufügen. In diesem Fall können Sie eine UPDATE-Anweisung schreiben, die die obige Abfrage SELECT als Unterabfrage enthält. Da MySQL nicht dieselbe Tabelle für die UPDATE und die Unterabfrage verwenden kann, müssen Sie die Unterabfrage in eine andere SELECT umbrechen, damit MySQL aus Ihren Ergebnissen eine temporäre Tabelle generiert.

UPDATE starting_pitcher_stats c 
SET c.std_F_parkfactor = (
    SELECT d.std_F_parkfactor FROM (
     SELECT 
      a.Starting_Pitcher, 
      AVG(b.full_park_factor) std_F_parkfactor, 
      a.Game_Date, a.Game_Number 
     FROM starting_pitcher_stats a 
     INNER JOIN starting_pitcher_stats b 
      ON a.Starting_Pitcher = b.Starting_Pitcher 
      AND (b.Game_Date < a.Game_Date OR 
       (b.Game_Date = a.Game_Date 
        AND b.Game_Number <= a.Game_Number)) 
      AND YEAR(b.Game_Date) = YEAR(a.Game_Date) 
     GROUP BY a.Starting_Pitcher, a.Game_Date, a.Game_Number 
    ) d 
    WHERE c.Starting_Pitcher = d.Starting_Pitcher 
    AND c.Game_Date = d.Game_Date 
    AND c.Game_Number = d.Game_Number 
); 
+0

Ja, ich denke, das ist es - die vorletzte Zeile kann oder kann nicht notwendig sein – Strawberry

+0

Matt, danke! Das funktioniert großartig. Jetzt versuche AVG (b.full_park_factor) Feld als Spalte zur Tabelle hinzuzufügen mit "ALTER TABLE startupitcher_stats ADD COLUMN AVG (b.full_park_factor), aber es wird nicht funktionieren ... Die Game_Number Spalte bezieht sich nur auf die Spielnummer von ein doppelter Header, wenn er an einem bestimmten Datum auftrat (dh 0 = Spiel 1; 1 = Spiel 1 des Doppelheaders, wenn es aufgetreten ist; 2 = Spiel 2 eines Doppelheaders). Aber ich kann diese Spalte einfach zum Code hinzufügen Danke, – LeeZee

+0

MySQL [unterstützt nicht die Verwendung von Ausdrücken in Standardwerten] (http://stackoverflow.com/questions/270309/cani-i-use-a-function-for-a-default-value- in-mysql). Sie könnten einen Trigger schreiben, um eine Spalte in der Tabelle beim Einfügen zu aktualisieren, aber es funktioniert nur, wenn Sie die Statistiken immer in der Datumsreihenfolge eingeben. In der Minute, in der Sie eine verpassen und später eingeben müssen, müssen Sie Aktualisieren Sie alle folgenden Datensätze in der Tabelle: Sie sollten besser in die Erstellung einer Ansicht aus Ihrer SELECT-Anweisung (http://dev.mysql.com/doc/refman/5.7/en/create-view) schauen. html) abhängig von o n Ihre Anforderungen. –

0

UPDATE: Hier ist ein Weg, um die Saison-to-date zu speichern (in der Saison) Park-Faktor Durchschnitt einer Saison in einer Spalte, die in diesem Fall ist der Durchschnitt der anderen Werte der Spalte in der gleiche Tabelle mit einer gespeicherten Prozedur. Es berechnet im Wesentlichen den Durchschnitt, indem es durch die Zeilennummer dividiert, die der Anzahl der Zeilen von Werten entspricht, die bei der Berechnung dieser Variablen durchlaufen wurden. Dieser Ansatz funktioniert, wenn Sie bereits Daten gesammelt haben, die Sie auf einmal oder nur selten aktualisieren möchten, aber wie von Matt Raines impliziert, muss er möglicherweise häufiger ausgeführt werden als seine vorgeschlagenen Ansätze. Wenn die Tabelle häufig mindestens einmal täglich mit den Daten der Spieleergebnisse der aufeinanderfolgenden Tage aktualisiert wird, denke ich, dass es weniger arbeitsintensiv ist, seinen Ansatz zu verwenden. Bitte lassen Sie mich wissen, was beseitigt werden kann:

DROP PROCEDURE IF EXISTS std_park_factor_avg; 
DELIMITER $$ 
CREATE PROCEDURE std_park_factor_avg() 
BEGIN 
    DECLARE pit_id CHAR(10); 
    DECLARE lgID CHAR (2); 
    DECLARE YEARID INT; 
    DECLARE gdate DATE; 
    DECLARE seq INT; 
    DECLARE F_park_factor INT; 
    DECLARE RNUMBER INT; 
    DECLARE accum_F_parkfactor REAL; 
    DECLARE accum_row_number INT; 
    DECLARE accum_avg_F_parkfactor REAL; 
    DECLARE prev_year YEAR(4); 
    DECLARE end_of_cursor BOOLEAN; 

    DECLARE no_table CONDITION FOR SQLSTATE '42S02'; 

    DECLARE c1 CURSOR FOR 
     SELECT Starting_Pitcher, lg_ID, YEAR_ID, Game_Date, Game_Number, full_park_factor, ROW_NUMBER 
     FROM starting_pitcher_stats 
     GROUP BY Starting_Pitcher, lg_ID, YEAR_ID, Game_Date, Game_Number; 

    DECLARE CONTINUE HANDLER FOR NOT FOUND 
     SET end_of_cursor := TRUE; 

    SET end_of_cursor := FALSE; -- reset 
    SET prev_year := 0;   -- reset control-break 

    OPEN c1; 

    fetch_loop: LOOP 
     FETCH c1 INTO pit_id, lgID, YEARID, gdate,seq, F_park_factor, RNUMBER; 
     IF end_of_cursor THEN 
     LEAVE fetch_loop; 
     END IF; 

     -- check control-break conditions 
     IF YEAR(gdate) != prev_year THEN 
     SET accum_F_parkfactor := 0.0; 
     SET RNUMBER:= 1.0; 
     SET accum_avg_F_parkfactor := 0.0; 
     SET prev_year := YEAR(gdate); 
     END IF; 

    SET accum_F_parkfactor := accum_F_parkfactor + F_park_factor; 
    SET accum_avg_F_parkfactor := accum_F_parkfactor/RNUMBER; 

     UPDATE starting_pitcher_stats 
     SET std_F_parkfactor =accum_avg_F_parkfactor 
     WHERE Starting_Pitcher = pit_id 
      AND lg_ID = lgID 
      AND YEAR_ID = YEARID 
      AND Game_Date = gdate 
      AND Game_Number = seq; 

    END LOOP; 
    CLOSE c1; 
    END 
$$ 

DELIMITER ; 
Verwandte Themen