Saran terbaik saya untuk Anda adalah, Jangan lakukan ini. Menyimpan informasi yang dapat diturunkan dari informasi lain dalam database umumnya dianggap desain yang sangat buruk, dan berusaha mengandalkan urutan baris dalam database adalah jalan pasti menuju kegilaan.
Inilah cara pertama untuk menormalkan tabel Anda:
-- 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;
(Saya tidak mengikuti bisbol, jadi saya hanya bisa menebak beberapa nama kolom.) Perhatikan bahwa year_id
, month_id
dan day_id
kolom hilang, karena nilai tersebut dapat dibuat kembali dari game_date
kolom seperti yang saya tunjukkan di komentar. Juga game_id
. Anda kolom hilang; ini dapat dibuat ulang dari menggabungkan opposing_team
, game_date
dan game_seq
(yang saya kira adalah untuk memperhitungkan tajuk ganda &c.) Saya juga telah mengonversi W
dan L
menjadi satu kolom yang dimaksudkan untuk menampung nilai "W" (menang), "L" (kalah), dan "T" (seri).
teams
table menyediakan tabel pencarian untuk id tim 3-char. Itu dapat diperluas untuk menampung data tim lain yang Anda inginkan. (Perhatikan bahwa ini dimaksudkan untuk menggambarkan tim itu sendiri; tim aktivitas akan pergi ke meja lain.)
Untuk menjawab pertanyaan Anda tentang klausa "kendala", yang pertama (CONSTRAINT starting_pitcher_log_pk
dan garis indentasi di bawahnya) menetapkan bahwa rangkaian ketiga kolom tersebut berfungsi sebagai pengidentifikasi unik utama untuk setiap baris dalam tabel. Yang kedua (CONSTRAINT team_fk FOREIGN KEY (opposing_team)
dan garis indentasi di bawahnya) berarti bahwa untuk nilai yang akan ditempatkan di opposing_team
kolom itu harus sudah ada di teams.team_id
kolom; Anda tidak bisa bermain melawan tim yang tidak ada.
Sekarang untuk benar-benar menjawab pertanyaan awal Anda. Solusi terbaik yang dapat saya temukan di MySQL adalah tabel awal dan prosedur tersimpan, sebagai berikut:
-- 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;
Dan prosedur tersimpan:
------------------------------------------------------------------------------ --
-- 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
Prosedur ini menghapus tabel ip_subtotal
, mengisinya dari tabel utama, lalu menggulung total lari untuk pitch inning. Ini juga menggunakan kontrol-break sederhana untuk mengatur ulang akumulator pada awal tahun. Setelah Anda menjalankan prosedur dengan menjalankan
CALL accumulate_innings();
Anda dapat menanyakan ip_subtotal
tabel atau gabungkan kembali ke starting_pitchers_game_log
tabel sesuai keinginan.
Prosedur juga dapat diperpanjang untuk menerima tanggal mulai dan berakhir; Saya meninggalkan itu sebagai latihan untuk pembaca.
Semoga ini membantu; itu menarik dan memaksa saya untuk belajar sedikit MySQL.