【问题标题】:Is there a SQL table constraint to ensure that a relationship exists between two columns?是否有 SQL 表约束来确保两列之间存在关系?
【发布时间】:2017-01-20 06:53:43
【问题描述】:

我正在尝试解决以下问题。

CREATE TABLE leagues (
    id SERIAL PRIMARY KEY,
    name TEXT,
    ...
);

CREATE TABLE players (
    id SERIAL PRIMARY KEY,
    first_name TEXT,
    last_name TEXT,
    ...
);

CREATE TABLE league_members (
    league_id INTEGER REFERENCES leagues (id),
    player_id INTEGER REFERENCES players (id),
    PRIMARY KEY (league_id, player_id)
);

CREATE TABLE games (
    id SERIAL PRIMARY KEY,
    league_id INTEGER REFERENCES leagues (id),
    winner INTEGER REFERENCES players (id),
    loser INTEGER REFERENCES players (id)
);

在比赛表中,我是否可以使用一个约束来检查以确保赢家和输家都是同一个联赛的成员?

例如:

球员表:

---- id ---- first_name ----
     1       "John"
     2       "Joe"
     3       "Jill"

联赛表:

---- id ---- name ----
     1       "League 1"
     2       "League 2"

league_members 表:

---- id ---- league_id ---- player_id ----
     1           1              1
     2           1              2
     3           2              3

我想确保在游戏表中以下内容会导致错误:

INSERT INTO games (league_id, winner, loser) VALUES (1,1,3);

这是不允许的,因为球员 3 不在联赛 1 中。现在我只是在 League_members 表上运行这个查询:

SELECT count(*) FROM league_members WHERE league_id = 1 AND (player_id = 1 OR player_id = 3);

他们确保计数为 2,这意味着两名球员都是 id 为 1 的联盟成员。如果计数为 2,则我允许插入游戏表,否则我不允许。有没有办法做到这一点,但让数据库处理约束,这样我就不必在尝试插入游戏表之前进行额外的查询?

谢谢!

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    几个外键应该保持直截了当:

    CREATE TABLE games (
        id SERIAL PRIMARY KEY,
        league_id INTEGER REFERENCES leagues (id),
        winner INTEGER REFERENCES players (id),
        loser INTEGER REFERENCES players (id),
        constraint FK_League_Winner FOREIGN KEY (league_id,winner)
           REFERENCES league_members (league_id,player_id),
        constraint FK_League_Loser FOREIGN KEY (league_id,loser)
           REFERENCES league_members (league_id,player_id)
    );
    

    由于这两个键共享此表中的league_id 列,因此不可能出现成员来自不同联赛的情况。

    【讨论】:

    • 太棒了!非常感谢!
    猜你喜欢
    • 2020-04-08
    • 1970-01-01
    • 2018-06-20
    • 2011-12-29
    • 2018-12-14
    • 2016-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多