2016-05-14 8 views
0

私のテーブル "starting_pitcher_stats"に列(平均park_factor)別の列(park_factor)の値の季節から季節までの平均値を含むことができます。私はこのシーズン平均をピッチャーと日付でグループ化したいと思っています。MySQLを使用して同じテーブルの別の列の値の季節別平均値を持つ列を作成しようとしています

理想的には、表は次のようになります。

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

...と結果のテーブルのサンプルは次のようになります:

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 

私が使用しているコードがある

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 

誰か助けてもらえますか?

ありがとうございました。 Lee

+1

私はあなたに私たちがあなたを援助したいと思うか分かりません。希望の結果に対応する適切なCREATE文とINSERT文を提供することを検討してください。 – Strawberry

+0

こんにちは、私は、対応する行の値の平均値+前の日付からの行の値を持つ列avg_Park_factorを作成したいと考えていますpark_factors列。 – LeeZee

答えて

2

同じテーブルの同じ投手の以前の結果すべてにテーブルに参加する必要があります。

季節をどのように定義するのかよく分かっていませんが、それが暦年であると仮定すると、次のクエリは望ましい出力を生成します。

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; 

テーブルの列をこの計算の結果で更新したいと思われるようです。これは、既存のデータを挿入または更新するか、またはビューを使用するたびに列を更新するトリガーを使用して、リアルタイム更新で実現できます。あなたはので、おそらく、あなたがデータを挿入すると、列の更新を持っている必要はありませんが、単純に、一度にテーブル内のすべてのレコードの平均列を更新する手順を作成し、あなた自身の答えで

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; 

オンデマンドですべての行の平均を追加することができます。この場合、上記のSELECTクエリをサブクエリとして含むUPDATE文を記述することができます。 MySQLはUPDATEとサブクエリで同じテーブルを使用できないため、サブクエリを別のSELECTにラップすると、結果から一時テーブルが生成されます。

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

うん、私はそれだと思う - 最後から二番目の行が必要かもしれません。 – Strawberry

+0

マット、ありがとう!これは素晴らしいです。これで、AVG(b.full_park_factor)フィールドを "ALTER TABLE starting_pitcher_stats ADD COLUMN AVG(b.full_park_factor)"というテーブルに列として追加しようとしましたが、動作しません... Game_Number列は、 (すなわち、0 =ゲーム1; 1 =ダブルヘッダーのゲーム1が発生した場合は2; =ダブルヘッダーのゲーム2の場合)。しかし、私はその列をコードに追加することができます。ありがとうございます。 – LeeZee

+0

MySQL [デフォルト値での式の使用をサポートしていません](http://stackoverflow.com/questions/270309/can-i-use-a-function-for-a-default-value- in-mysql)挿入時に表の列を更新するトリガーを作成することはできますが、常に日付順に統計を入力すると機能します。後で入力する必要がある場合は、テーブルの次のすべてのレコードを更新してください。[SELECTステートメントからのビューの作成](http://dev.mysql.com/doc/refman/5.7/en/create-view。 html)に応じてあなたの必要条件 –

0

UPDATE:ここでは、この場合に別の列の値の平均値である列に与えられたシーズンのシーズン・ツー・日付(インシーズン)公園因子平均を格納するための方法ですストアドプロシージャを使用して同じテーブル。基本的には、この変数の計算でループされた値の行数に対応するrow_numberで除算して平均を計算します。このアプローチは、あなたが一度に更新したいデータを既に収集している場合、またはMatt Rainesが暗示するように、提案されたアプローチより頻繁に実行する必要があるかもしれません。テーブルが頻繁に更新され、少なくとも1日に1回以上の連続したゲームの結果からのデータが頻繁に更新されるようであれば、彼のアプローチを使うのは労働集約的ではないと思う。除外できるものを教えてください:

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 ;