Использование нескольких внешних ключей в операторе выбора SQL - PullRequest
0 голосов
/ 07 апреля 2020

У меня есть четыре таблицы, одна из которых называется матчами, а другая - командами. Мне нужно отобразить код команды в командах с указанием количества очков, которое мы можем вычислить в матчах. Каждый выигрыш составляет 2 очка, каждый тянет одно очко и каждый теряет ноль.

CREATE TABLE divisions 
(
    codediv  CHAR(1) NOT NULL,
    nomdiv   VARCHAR2(40)
);

ALTER TABLE divisions 
    ADD CONSTRAINT divisions_pk PRIMARY KEY (codediv);

CREATE TABLE teams 
(
    teamCode CHAR(3) NOT NULL,
    teamName   VARCHAR2(50),
    codediv     CHAR(1) NOT NULL,
    ville       VARCHAR2(40),
    nbcoupes    NUMBER
);

ALTER TABLE teams ADD CHECK (nbcoupes >= 0);

ALTER TABLE teams ADD CONSTRAINT teams_pk PRIMARY KEY (teamCode);

CREATE TABLE joueurs 
(
    numjoueur   NUMBER(3) NOT NULL,
    nom         VARCHAR2(30),
    prenom      VARCHAR2(30),
    codeequipe  CHAR(3)
);

ALTER TABLE joueurs ADD CONSTRAINT joueurs_pk PRIMARY KEY (numjoueur);

CREATE TABLE matchs 
(
    MatchNumber NUMBER(4) NOT NULL,
    datematch DATE,
    codeVisitingTeam CHAR(3) NOT NULL,
    codeReceivingTeam CHAR(3) NOT NULL,
    scoreVisitingTeam NUMBER(2),
    scoreReceivingTeam NUMBER(2)
);

ALTER TABLE matchs ADD CONSTRAINT matchs_pk PRIMARY KEY (MatchNumber);

CREATE TABLE statistiques 
(
    nummatch   NUMBER(4) NOT NULL,
    numjoueur  NUMBER(3) NOT NULL,
    nbbuts     NUMBER(3),
    nbpasse    NUMBER(3)
);

ALTER TABLE statistiques 
    ADD CONSTRAINT statistiques_pk PRIMARY KEY (numjoueur, nummatch);

ALTER TABLE matchs
    ADD CONSTRAINT codeVisitingTeam FOREIGN KEY ( codeVisitingTeam)
        REFERENCES teams ( teamCode );

ALTER TABLE teams
    ADD CONSTRAINT teams_divisions_fk FOREIGN KEY ( codediv )
        REFERENCES divisions ( codediv );

ALTER TABLE joueurs
    ADD CONSTRAINT joueurs_equipes_fk FOREIGN KEY ( teamCode )
        REFERENCES equipes ( teamCode );

ALTER TABLE matchs
    ADD CONSTRAINT matchs_equipes_fk FOREIGN KEY ( CodeReceivingTeam )
        REFERENCES equipes ( teamCode );

ALTER TABLE statistiques
    ADD CONSTRAINT statistiques_joueurs_fk FOREIGN KEY ( numjoueur )
        REFERENCES joueurs ( numjoueur );

ALTER TABLE statistiques
    ADD CONSTRAINT statistiques_matchs_fk FOREIGN KEY ( nummatch )
        REFERENCES matchs ( nummatch );

insert into divisions values('O', 'OUEST');
insert into divisions values('E', 'EST');

insert into equipes values('MTL', 'LES CANADIENS DE MONTRÉAl', 'E', 'MONTRÉAl', 24);
insert into equipes values('TOR', 'LES MAPLE LEAFS', 'E', 'TORONTO', 22);
insert into equipes values('OTT', 'LES SÉNATEURS', 'E', 'OTTAWA', 4);
insert into equipes values('AVL', 'LES AVALANCHES', 'O', 'COLORADO', 2);
insert into equipes values('VAN', 'LES CANUKS', 'O', 'VANCOUVER', 1);
insert into equipes values('BRU', 'LES BRUNS DE BOSTON', 'E', 'BOSTON', 13);

insert into Joueurs values(1, 'PRICE', 'CAREY', 'MTL');
insert into Joueurs values(2, 'MARKOV', 'ANDRÉ', 'MTL');
insert into Joueurs values(3, 'SUBBAN', 'KARL', 'MTL');
insert into Joueurs values(4, 'PATIORETTY', 'MAX', 'MTL');
insert into Joueurs values(10, 'HAMMOND', 'ANDREW', 'OTT');
insert into Joueurs values(6, 'STONE', 'MARC', 'OTT');
insert into Joueurs values(9, 'TURIS', 'KYLE', 'OTT');
insert into Joueurs values(7, 'GALLAGHER', 'BRANDON', 'MTL');
insert into Joueurs values(8, 'TANGUAY', 'ALEX', 'AVL');
insert into Joueurs values(11, 'THOMAS', 'BIL', 'AVL');
insert into Joueurs values(5, 'PATOCHE', 'ALAIN', NULL);
insert into Joueurs values(12, 'POIRIER', 'JUTEUX', NULL);

insert into Matchs values(100, TO_DATE('18-10-30', 'YY/MM/DD'), 'MTL', 'TOR', 3 , 4);
insert into Matchs values(101, TO_DATE('18-11-10', 'YY/MM/DD'), 'TOR', 'MTL', 3 , 3);
insert into Matchs values(102, TO_DATE('18-10-12', 'YY/MM/DD'), 'MTL', 'OTT', 2 , 0);
insert into Matchs values(103, TO_DATE('18-10-20', 'YY/MM/DD'), 'OTT', 'MTL', 0 , 1);
insert into Matchs values(104, TO_DATE('18-11-30', 'YY/MM/DD'), 'MTL', 'AVL', 3 , 4);
insert into Matchs values(105, TO_DATE('18-11-10', 'YY/MM/DD'), 'AVL', 'MTL', 0 , 0);
insert into Matchs values(106, TO_DATE('18-12-12', 'YY/MM/DD'), 'MTL', 'VAN', 2 , 0);
insert into Matchs values(107, TO_DATE('18-03-17', 'YY/MM/DD'), 'VAN', 'MTL', 3 , 1);
insert into Matchs values(108, TO_DATE('18-11-30', 'YY/MM/DD'), 'OTT', 'VAN', 0 , 0);
insert into Matchs values(109, TO_DATE('18-11-10', 'YY/MM/DD'), 'OTT', 'TOR', 0 , 4);
insert into Matchs values(114, TO_DATE('18-10-30', 'YY/MM/DD'), 'BRU', 'TOR', 3 , 4);
insert into Matchs values(115, TO_DATE('19-02-15', 'YY/MM/DD'), 'AVL', 'TOR', null , null);
insert into Matchs values(120, TO_DATE('18-02-26', 'YY/MM/DD'), 'MTL', 'AVL', null , null);
insert into Matchs values(121, TO_DATE('19-02-20', 'YY/MM/DD'), 'MTL', 'OTT', null , null);

Insert into statistiques values(100,3,2,2);
Insert into statistiques values(100,7,1,1);
Insert into statistiques values(101,3,1,0);
Insert into statistiques values(101,7,0,1);
Insert into statistiques values(101,4,1,2);
Insert into statistiques values(101,2,1,2);
Insert into statistiques values(100,4,0,2);
Insert into statistiques values(102,3,1,1);
Insert into statistiques values(102,7,1,2);
Insert into statistiques values(102,9,0,1);
Insert into statistiques values(106,4,1,1);
Insert into statistiques values(106,3,0,2);
Insert into statistiques values(106,2,1,0);
Insert into statistiques values(100,1,null,null);
Insert into statistiques values(101,1,null,null);
Insert into statistiques values(103,1,null,null);
Insert into statistiques values(102,1,null,null);

Я начал с этого, чтобы получить выигравшие команды

select * 
from
    (select v.teamcode, count(m.codeVisitingTeam) as WonMatches
     from matchs m 
     join teams v on v.teamCode = m.codeVisitingTeam
     where m.scoreVisitingTeam > m.scoreReceivingTeam
     group by v.teamCode

     union all

     select r.codeequipe, count(m.codeequiper) as WonMatches
     from matchs m 
     join teams r on r.teamCode = m.codeReceivingTeam
     where m.scoreReceivingTeam > m.scoreVisitingTeam
     group by r.teamCode));

Единственная проблема с кодом выше является то, что он возвращает дважды команду «MTL», как это:

VAN 1
MTL 2
AVL 1
TOR 3
MTL 1

Ответы [ 2 ]

1 голос
/ 08 апреля 2020

Так что я немного повеселился с вашим запросом и сделал немного больше, чем вы просили. Я написал следующий запрос, чтобы рассчитать полный набор выигрышей, проигрышей и ничьих. Затем я упорядочил результаты по очкам (3 очка за победу и 1 за ничью). Надеюсь, это вам немного поможет:

SELECT *
FROM (SELECT TeamCode,
             CASE 
               WHEN (team = 'VISTING' AND scoreVisitingTeam > SCORERECEIVINGTEAM) OR (team = 'RECEIVING' AND SCORERECEIVINGTEAM > SCOREVISITINGTEAM) THEN 'WIN'
               WHEN (team = 'VISTING' AND scoreVisitingTeam < SCORERECEIVINGTEAM) OR (team = 'RECEIVING' AND SCORERECEIVINGTEAM < SCOREVISITINGTEAM) THEN 'LOSS'
               ELSE 'DRAW'
             END AS RESULT
      FROM matchs
      UNPIVOT (TeamCode FOR Team IN (CodeVisitingTeam AS 'VISTING', CodeReceivingTeam AS 'RECEIVING')))
PIVOT(COUNT(*) FOR RESULT IN ('WIN' AS WINS, 'LOSS' AS LOSSES, 'DRAW' AS DRAWS))
ORDER BY (wins*3)+draws DESC;

Если у вас есть вопросы, пожалуйста, дайте мне знать.

Я также создал SQLFiddle. ( Ссылка ) Примечание. Я удалил ваши ограничения из SQLFiddle. Они выдавали ошибки, и мне не хотелось отлаживать их.

1 голос
/ 07 апреля 2020

Вы можете сделать это в одном запросе с условным агрегированием:

select e.teamCode,
  sum(
    case 
      when (e.teamCode = m.codeReceivingTeam and m.scoreReceivingTeam > m.scoreVisitingTeam)
        or (e.teamCode = m.codeVisitingTeam and m.scoreReceivingTeam < m.scoreVisitingTeam) then 2
      when m.scoreReceivingTeam = m.scoreVisitingTeam then 1
      else 0
    end
  ) total_points
from equipes e inner join matchs m
on e.teamCode in (m.codeReceivingTeam, m.codeVisitingTeam)
group by e.teamCode
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...