Sql 如何处理两个几乎相同的表

Sql 如何处理两个几乎相同的表,sql,sqlite,Sql,Sqlite,我有一张棒球统计表,类似这样: CREATE TABLE batting_stats( ab INTEGER, pa INTEGER, r INTEGER, h INTEGER, hr INTEGER, rbi INTEGER, playerID

我有一张棒球统计表,类似这样:

CREATE TABLE batting_stats(
    ab                INTEGER,
    pa                INTEGER,
    r                 INTEGER,
    h                 INTEGER,
    hr                INTEGER,
    rbi               INTEGER,
    playerID          INTEGER,
    FOREIGN KEY(playerID) REFERENCES player(playerID)
);
但是我有一个基本上完全相同的统计表,但是对于一个团队来说:

CREATE TABLE team_batting_stats(
    ab                INTEGER,
    pa                INTEGER,
    r                 INTEGER,
    h                 INTEGER,
    hr                INTEGER,
    rbi               INTEGER,
    teamID            INTEGER,
    FOREIGN KEY(teamID) REFERENCES team(teamID)
);
我的第一反应是放弃外键并泛化ID,但我仍然有一个问题,我有这两个表,它们不能有重叠的ID:

CREATE TABLE player(
    playerID    INTEGER PRIMARY KEY,
    firstname   TEXT,
    lastname    TEXT,
    number      INTEGER,
    teamID      INTEGER,
    FOREIGN KEY(teamID) REFERENCES team(teamID)
);

CREATE TABLE team(
    teamID      INTEGER PRIMARY KEY,
    name        TEXT,
    city        TEXT,
);

我觉得我忽略了一些显而易见的东西,这些东西可以解决这个问题,并将统计数据简化为一个表。

您需要重新审视数据的结构以及您试图捕获数据的内容(以及方式)。如果球队像大联盟俱乐部一样是“永久性”的,或者像小联盟球队一样是临时性的,那就不同了。前者比后者容易,但后者的解决方案也适用于前者

你还需要决定你想保持数据的正常化程度——如果你知道哪个击球手面对哪个投手,那么可以从击球数据中得出哪个投手的数据,但这可能比它的价值更复杂

原子项目是玩家、团队和游戏。交易会发生,但我猜在第6局和第7局之间不会发生。因此,比赛是球队和球员之间的纽带

所以你会得到这样的表格:

PlayerID   Name    Dog's Name
   1       Fred     Fluffy
   2       Joe      Spike

TeamID    Name      Mascot
   1      Chicago   Comets
   2      Timbuktu  Pussy Cats

GameID    Date        Location     Season
   1      2012-18-12  Over there    2012
   2      2011-20-4   The Park      2011

GameID    PlayerID   TeamID     AllTheStatsFromThisPlayerAtThisGame
   1         1          1
   1         2          2
玩家统计数据是他所玩的所有游戏的集合。
球队统计数据是球队中所有球员在所有比赛中的集合。

如果你想将统计数据减少到一个表中,你可以添加两个关系表,将击球手或球队链接到统计表中

实体表:

CREATE TABLE stats(
    statsID          INTEGER primary key,
    ab                INTEGER,
    pa                INTEGER,
    r                 INTEGER,
    h                 INTEGER,
    hr                INTEGER,
    rbi               INTEGER
);

CREATE TABLE player(
    playerID    INTEGER PRIMARY KEY,
    firstname   TEXT,
    lastname    TEXT,
    number      INTEGER,
    teamID      INTEGER,
    FOREIGN KEY(teamID) REFERENCES team(teamID)
);

CREATE TABLE team(
    teamID      INTEGER PRIMARY KEY,
    name        TEXT,
    city        TEXT,
);
将击球手/球队链接到统计数据的关系表:

CREATE TABLE batting_stats(
    playerID integer not null REFERENCES player(playerID),
    statsID integer not null REFERENCES stats(statsID),
    primary key (playerID, statsID)
);

CREATE TABLE team_batting_stats(
    teamID integer not null REFERENCES team(teamID),
    statsID integer not null REFERENCES stats(statsID),
    primary key (teamID, statsID)
);

为什么将其缩减为一个表更可取?看起来分开的桌子是最好的选择。不过,你可能想考虑加入一季FK。似乎您需要一个球员和球队的赛季加入表,然后使用球员/赛季键作为统计表中的FK。如果球员没有从一个球队移动到另一个球队,您可以完全删除球队的击球统计。然后使用sum()Select语句on batting_stats internal JOIN player on batting_stats.playerID=player.playerID GROUP BY player.teamID来获取整个团队的统计信息。我有如下函数:save_player,这些函数非常多毛,可以重复用于save_team。这将意味着在我的应用程序中大量减少代码。还有一个
pitching_stats
team_pitching_stats
表格可以组合。哦,球员肯定会在球队之间移动,这是乐趣的一半。我也在考虑赛季,你是对的@tvanfosson。