PostgreSQL问题,约束和查询

时间:2018-03-31 05:38:38

标签: sql postgresql

我的任务是制作一张表格,记录竞赛赛事中参加比赛的赛车车手赢得的位置。

给定的架构是:

CREATE TABLE RaceEvent 
(
    Name text,
    Year int, 
);

CREATE TABLE Driver 
(
    Name text,
    Date_of_birth date,
    Gender char,
    Nationality,
);

然后我添加了以下约束:

CREATE TABLE RaceEvent 
(
     RaceName text NOT NULL PRIMARY KEY,
     Year int NOT NULL,
     Description text NOT NULL 
);

CREATE TABLE Driver 
(
    Name text  NOT NULL,
    Date_of_birth date  NOT NULL PRIMARY KEY,
    Gender char(1)  NOT NULL,
    Nationality text  NOT NULL
);

我创建的表格如下:

CREATE TABLE Races 
(
    Medal char(6) CHECK (Medal = 'Gold' or Medal = 'Silver' or Medal = 
'Bronze'),
    Event text NOT NULL REFERENCES RaceEvent (Name),
    DriverDOB date NOT NULL REFERENCES Driver (Date_of_birth) 
);

我知道使用出生日期作为主键是非常愚蠢的,但出于某种原因这是任务的一部分。

我需要确保一名车手不能在同一场比赛中获得多枚奖牌,任何人都可以通过这种方式深入了解这一点吗?我考虑过使用某种检查,但不能完全解决。

在那之后,我需要写一个可以返回在某些年份赢得至少2枚金牌的车手国籍的查询,以确定哪些国籍​​似乎能产生最好的车手。同一查询的2个版本,一个使用聚合,一个不使用聚合。 我知道我必须按照这些方针做点什么:

SELECT Nationality from Driver JOIN Races ON Driver.Date_of_Birth = Races.DriverDOB WHERE ....?

不确定如何确定如何将国籍与奖牌联系起来的最佳方法? 所有反馈都非常赞赏

1 个答案:

答案 0 :(得分:0)

“最好”的方法是重构您的架构,因为现在它是相当废话。我假设你做不到,所以这里有一种方法可以阻止多个驱动程序在同一种族中获得多枚奖牌:在DriverDOBEvent上添加一个主键到Races表。

在此处试试:http://sqlfiddle.com/#!17/dc8a9/1

至于在特定年份获得多个金币的国籍的问题,这是一种方法:

SELECT d.nationality, COUNT(*) AS golds
FROM races r
JOIN driver d
  ON r.driverdob = d.date_of_birth
JOIN raceevent e
  ON r.event = e.racename
  AND e.year = 1999
WHERE r.medal = 'Gold'
GROUP BY d.nationality
HAVING COUNT(*) > 1;

输出:

nationality golds
NatA        3
NatB        2

你可以在这里测试一下:http://sqlfiddle.com/#!17/dc8a9/9