SQL Server — внешний ключ, ссылающийся на первичный ключ A OR B

Скажем, у меня есть таблица Matchup, содержащая две спортивные команды. У меня также есть таблица Pick, в которой есть столбец, который должен соответствовать Team_A ИЛИ Team_B. Так что это внешний ключ одного ИЛИ другого столбца в Matchup. Это возможно?

Матчап
Team_A
Team_B

Выберите
Pick_Team — FK Matchup (должен соответствовать Team_A или Team_B из Matchup).


person OperationNewDay    schedule 13.08.2013    source источник
comment
Добавьте свой комментарий (ответ астандера) в тело вопроса. Теперь ясно, что у вас должен быть третий стол со всеми командами, верно? Затем таблица Pick может иметь FK, нацеленный на PK этой таблицы.   -  person OzrenTkalcecKrznaric    schedule 13.08.2013


Ответы (2)


Я бы разделил вашу таблицу Matchup на две: собственно Matchup и MatchupDetails.

Таблица Matchup будет иметь столбец MatchupID в качестве первичного ключа.

MatchupDetails будет состоять как минимум из двух столбцов: MatchupID для ссылки на таблицу Matchup и TeamID для ссылки на таблицу Team (у вас ведь есть такая, не так ли?). Два столбца образуют составной первичный ключ таблицы.

Наконец, будет эта таблица Pick. Поскольку у вас есть несколько пользователей (согласно одному из ваших комментариев), должна быть ссылка UserID. Еще два столбца, MatchupID и TeamID, будут служить составным внешним ключом, ссылающимся на соответствующий столбец, установленный в MatchupDetails. И чтобы гарантировать, что один пользователь может выбрать не более одной команды из матча, составной первичный ключ (UserID, MatchupID) должен подойти.

Подводя итог, вот полный план соответствующей части схемы:

  • Matchup:

    MatchupID
    PRIMARY KEY (MatchupID)
    
  • MatchupDetails:

    MatchupID
    TeamID
    FOREIGN KEY (MatchupID)
    FOREIGN KEY (TeamID)
    PRIMARY KEY (MatchupID, TeamID)
    
  • Pick:

    UserID
    MatchupID
    TeamID
    FOREIGN KEY (UserID)
    FOREIGN KEY (MatchupID, TeamID)
    PRIMARY KEY (UserID, MatchupID)
    
person Andriy M    schedule 13.08.2013
comment
Да, у меня есть таблицы Team и User. Я считаю, что это или какой-то близкий вариант - это то, что я ищу. Спасибо! (Я бы проголосовал за ответ, но у меня пока недостаточно репутации...) - person OperationNewDay; 13.08.2013
comment
Хорошо, я попробовал это, и это прекрасно работает. Сначала я был сбит с толку, потому что таблица Matchup в приведенном выше примере имеет только идентификатор. Я добавил «Matchup_Date» и «Matchup_Venue» вместе с несколькими другими столбцами, и тогда это обрело смысл. - person OperationNewDay; 18.08.2013

Не думаю, что это правильный подход.

Я бы рекомендовал вам добавить дополнительное поле в таблицу Matchup (скажем, Pick) и добавить ПРОВЕРЬТЕ ОГРАНИЧЕНИЕ, чтобы убедиться, что это Team_A или Team_B.

Ограничения CHECK обеспечивают целостность домена, ограничивая значения, которые принимаются одним или несколькими столбцами. Вы можете создать ограничение CHECK с любым логическим (булевым) выражением, которое возвращает TRUE или FALSE на основе логических операторов.

Из Ограничения FOREIGN KEY

В ссылке по внешнему ключу связь создается между двумя таблицами, когда на столбец или столбцы, содержащие значение первичного ключа для одной таблицы, ссылается столбец или столбцы в другой таблице. Этот столбец становится внешним ключом во второй таблице.

И это не похоже на то, что вы ищете.

person Adriaan Stander    schedule 13.08.2013
comment
Это может быть то, что я ищу. Чтобы расширить пример, у меня есть несколько пользователей, выбирающих, кто выиграет в этой игре, поэтому я вынес их в отдельную таблицу. Помещение Picks в ту же таблицу, что и Matchup, поможет победить это. Может ли контрольное ограничение ссылаться на столбцы из другой таблицы? - person OperationNewDay; 13.08.2013
comment
Из stackoverflow.com /questions/3880698/ кажется, что вы можете создать UDF, который выполнит то, что вам нужно. - person Adriaan Stander; 13.08.2013