簡體   English   中英

如何添加在同一表的另一列上遞增的列?

[英]How can I add a column that increments on another column in same table?

我有一個表,該表的列名為“ IP”,我想在同一表“ YTD_IP”中創建另一列,該列將為任何給定游戲提供累計的年初至今“ IP”(總局)的總和。在一年中反映了同一季節之前的比賽(行/事件)中的總局數。 年份一旦發生變化,我希望總和再次從0開始。

這是“ PIT_ID”,“ YEAR_ID”,“ IP”列的數據示例,以及我希望看到的“ YTD_IP”列如下所示:

Pit_ID  YEAR_ID  IP      YTD_IP
aased001      1977  9.0000    9
aased001      1977  9.0000    18
aased001      1977  7.0000    25
aased001      1977  5.0000    30
aased001      1977  6.3333    36.3333
aased001      1977  6.3333    42.6666
aased001      1977  7.0000    49.6666
aased001      1977  6.0000    55.6666
aased001      1977  9.0000    64.6666
aased001      1977  9.0000    73.6666
aased001      1977  5.0000    78.6666
aased001      1977  6.3333    84.9999
aased001      1977  7.3333    92.3333
aased001      1978  4.3333     4.3333
aased001      1978  7.0000    11.3333
aased001      1978  6.3333    17.6666
aased001      1978  3.3333    20.9999

我整理了以下代碼:

ALTER TABLE starting_pitcher_game_log ADD COLUMN YTD_IP VARCHAR(255);
    SET YTD_IP:= 0;
    SELECT a.IP,  b.YEAR_ID
      IF(@prevYEAR_ID != YEAR_ID,IP,@YTD_IP+IP) AS IP,
      @prevYEAR_ID=YEAR_ID
    FROM starting_pitcher_game_log

但這不正確,因為它收到以下錯誤:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF(@prevYEAR_ID != YEAR_ID,IP,@YTD_IP+IP) AS IP,
          @prevYEAR_ID=YEAR_ID
' at line 2

有沒有辦法確保它可以容納將來要玩的游戲?

任何幫助都會大有幫助。

全表屏幕截圖

嗨,達爾文,

您可以共享適用於臨時調用列的代碼,也可以共享可創建累積總和字段的永久代碼嗎? 特別是,我想在名為“ YTD_IP”的表中創建另一列,該列將提供從賽季開始到該賽季中任何給定比賽的“ IP”(局點)的累計年初至今總和。反映給定投手在給定游戲之前的游戲(行/事件)中所投的局數之和+該游戲中所投的局數。 一旦季節發生變化,我希望總和再次從0開始。

預先感謝您的幫助。

對您最好的建議是,不要這樣做。 通常認為可以從數據庫中的其他信息中獲取信息是非常糟糕的設計,並且嘗試依賴數據庫中行的順序是避免問題的可靠途徑。

這是標准化表格的第一步:

-- Table: teams

-- DROP TABLE teams;

CREATE TABLE teams
(
  team_id character(3) primary key,
  team_name varchar(255),
  team_city varchar(255)
) engine=innodb;

-- Table: starting_pitchers_game_log

-- DROP TABLE starting_pitchers_game_log;

CREATE TABLE starting_pitchers_game_log
(
  pitcher_id character(10) NOT NULL,
  game_date date NOT NULL,
  opposing_team character(3),
  game_seq integer NOT NULL,
  outcome character(1),
  innings_pitched real,
  bfp integer,
  hits integer,
  runs integer,
  errors integer,
  homeruns integer,
  bb integer,
  k integer,
  ibb integer,
  hbp integer,
  wp integer,
  balks integer,
  CONSTRAINT starting_pitcher_log_pk
      PRIMARY KEY (pitcher_id , game_date , game_seq ),
  CONSTRAINT team_fk FOREIGN KEY (opposing_team)
      REFERENCES teams (team_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
) engine=innodb;

(我不追蹤棒球,所以我只能猜測其中的一些列名稱。)請注意, year_idmonth_idday_id列已消失,因為可以按照我在注釋中指示的那樣從game_date列中重新創建這些值。 您的game_id列也消失了; 這可以從串聯重新創建opposing_teamgame_dategame_seq (我假定是占雙頭&C)。我也轉換WL成用於保持值“W”(WIN)的單個列中,“ L”(損失)和“ T”(並列)。

teams表提供了一個由3個字符組成的球隊ID的查找表。 可以擴展它來保存您想要的任何其他團隊數據。 (請注意,這是為了描述團隊本身;團隊活動將放在另一個表中。)

為了回答有關“約束”子句的問題,第一個( CONSTRAINT starting_pitcher_log_pk和其下面的縮進行)指定將這三列的串聯用作表中每一行的主要唯一標識符。 第二個( CONSTRAINT team_fk FOREIGN KEY (opposing_team)和它下面的縮進的行)表示為被放置在一個值opposing_team柱它必須已經存在 teams.team_id柱; 您不能與不存在的團隊競爭。

現在開始實際回答您的原始問題。 我可以在MySQL上想到的最好的解決方案是臨時表和存儲過程,如下所示:

-- Table: ip_subtotal

-- DROP TABLE ip_subtotal;

CREATE TABLE ip_subtotal
(
  pitcher_id char(10) NOT NULL,
  game_date date NOT NULL,
  game_seq int(11) NOT NULL,
  innings_pitched double,
  ip_total double DEFAULT '0.0',
  CONSTRAINT ip_subtotal_pk
      PRIMARY KEY (pitcher_id , game_date , game_seq )
) ENGINE=InnoDB;

和存儲過程:

------------------------------------------------------------------------------    --
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$

CREATE PROCEDURE accumulate_innings()
BEGIN
    DECLARE pit_id CHAR(10);
    DECLARE gdate DATE;
    DECLARE seq INT;
    DECLARE in_pit REAL;
    DECLARE accum REAL;
    DECLARE prev_year YEAR(4);
    DECLARE end_of_cursor BOOLEAN;

    DECLARE c1 CURSOR FOR
        SELECT pitcher_id, game_date, game_seq, innings_pitched
            FROM ip_subtotal
            ORDER BY pitcher_id, game_date, game_seq;

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

    TRUNCATE TABLE ip_subtotal;
    INSERT INTO ip_subtotal
        SELECT pitcher_id, game_date, game_seq, innings_pitched, 0.0
            FROM starting_pitchers_game_log;

    SET prev_year := 0;
    OPEN c1;

    fetch_loop: LOOP
        FETCH c1 INTO pit_id, gdate, seq, in_pit;
        IF end_of_cursor THEN
            LEAVE fetch_loop;
        END IF;
        IF YEAR(gdate) != prev_year THEN
            SET accum := 0.0;
            SET prev_year := YEAR(gdate);
        END IF;
        SET accum := accum + in_pit;
        UPDATE ip_subtotal
            SET ip_total = accum
            WHERE pitcher_id = pit_id
              AND game_date = gdate
              AND game_seq = seq;
    END LOOP;
    CLOSE c1;
END

此過程將清除表ip_subtotal ,從主表中填充它,然后匯總運行的ip_subtotal 它還在年初通過簡單的控制中斷來重置累加器。 通過執行以下步驟運行過程之后

CALL accumulate_innings();

您可以查詢ip_subtotal表,或根據需要將其重新連接到starting_pitchers_game_log表。

該程序也可以擴展為接受開始和結束日期; 我把它留給讀者作為練習。

希望這可以幫助; 這很有趣,並迫使我學習一點MySQL。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM