某航空培训中心数据库设计与查询
Database design and query for a aviation training center
我在一家为客户租用飞机模拟器课程的公司工作。在进入模拟器之前,飞行员(客户)必须拥有他将驾驶的模拟器的有效队形。有效阵型是飞行员成功通过且未过期的阵型(所以我们要存储采集日期和过期日期)。
1。我的实体关系模型是否正确?
实体:
- Pilot : pilot_id, first_name, last_name, 其他身份字段.. .
- 模拟器 : simulator_id, 名称
关系:
- (0,n) 飞行员 接受过 (0,n) 模拟器培训:
将此代码复制粘贴到 http://mocodo.wingi.net/ 以直观地查看它:
DATE: _acquisition_date, _expiration_date
PILOT: id, first_name, last_name
is Trained For, 0n PILOT, 0n SIMULATOR, 0n DATE
SIMULATOR: id, name
不要忘记点击 'Refresh' 图标查看结果,就在
上方
2。对应的关系模型是否正确?
飞行员 ([id], first_name, last_name, ...)
接受过 的培训([pilot_id、simulator_id、acquisition_date、expiration_date])
模拟器 ([id], 名称)
其中 pilot_id 指的是... blablabla。
方括号定义了每个实体的主键。
3。我该如何回答这些问题?
- 哪些飞行员不能进入他们通过编队的模拟器?
- 在x个月通过编队的模拟器中,哪些飞行员会不适应,不包括那些已经不适应的飞行员?
我等待的输出如下所示:
+------------------------------------------------+
| Inapt pilots |
+------------+-----------------+-----------------+
| First name | Last name | Simulator |
+------------+-----------------+-----------------+
| John | Doe | Falcon 7X |
| John | Doe | Embraer ERJ 140 |
| Foo | Bar | Falcon 20 |
+------------+-----------------+-----------------+
为每个不称职的飞行员提供他不能去的模拟器。
首先,评论:您不需要 IS_TRAINED_FOR
table 中的到期日期。飞行员和模拟器 ID 加上采集日期就足够了。
回答您的问题:
是的,您的数据模型可用于所述目的。
除了我上面的评论,你的 table 定义没问题。
您要求的查询看起来像这样:
-- Get pilots that are no longer qualified for a simulator that they
-- have previously qualified for...
select distinct
P.first_name
, P.last_name
, S.name
from PILOT P
inner join IS_TRAINED_FOR T
on P.id = T.pilot_id
inner join SIMULATOR S
on T.simulator_id = S.id
where NOT EXISTS (select Q.acquisition_date
from IS_TRAINED_FOR Q
where Q.acquisition_date <= NOW()
and Q.expiration_date >= NOW()
and Q.pilot_id = T.pilot_id
and Q.simulator_id = T.simulator_id)
因为上面的查询使用了内连接,所以只会显示曾经获得模拟器资格的飞行员,但是因为WHERE子句,只有在他们的资格过期时才会显示。
请注意,使用相关子查询是因为如果飞行员的资格已过期但后来被更新(并且仍然有效),那么简单地说诸如到期日期小于 NOW() 之类的内容将失败。
要查看谁将在 X 个月内被取消资格,只需将 X 个月添加到上述查询中的 NOW() 中,如下所示:(对于此示例,假设 4 个月...)
DATE_ADD(NOW(),INTERVAL 4 MONTH)
要查看从现在到 x 个月后谁将被取消资格,请使用此查询:
-- Get pilots whose qualifications will be expiring for a simulator that they
-- are currently qualified for...
select distinct
P.first_name
, P.last_name
, S.name
from PILOT P
inner join IS_TRAINED_FOR T
on P.id = T.pilot_id
inner join SIMULATOR S
on T.simulator_id = S.id
where NOT EXISTS (select Q.acquisition_date
from IS_TRAINED_FOR Q
where Q.acquisition_date <= DATE_ADD(NOW(),INTERVAL 4 MONTH)
and Q.expiration_date >= DATE_ADD(NOW(),INTERVAL 4 MONTH)
and Q.pilot_id = T.pilot_id
and Q.simulator_id = T.simulator_id)
and T.acquisition_date <= NOW()
and T.expiration_date >= NOW()
and T.expiration_date <= DATE_ADD(NOW(),INTERVAL 4 MONTH
第二个查询显示在 4 个月内(例如)不合格并且他们现在合格的飞行员。
我在一家为客户租用飞机模拟器课程的公司工作。在进入模拟器之前,飞行员(客户)必须拥有他将驾驶的模拟器的有效队形。有效阵型是飞行员成功通过且未过期的阵型(所以我们要存储采集日期和过期日期)。
1。我的实体关系模型是否正确?
实体:
- Pilot : pilot_id, first_name, last_name, 其他身份字段.. .
- 模拟器 : simulator_id, 名称
关系:
- (0,n) 飞行员 接受过 (0,n) 模拟器培训:
将此代码复制粘贴到 http://mocodo.wingi.net/ 以直观地查看它:
DATE: _acquisition_date, _expiration_date
PILOT: id, first_name, last_name
is Trained For, 0n PILOT, 0n SIMULATOR, 0n DATE
SIMULATOR: id, name
不要忘记点击 'Refresh' 图标查看结果,就在
上方2。对应的关系模型是否正确?
飞行员 ([id], first_name, last_name, ...)
接受过 的培训([pilot_id、simulator_id、acquisition_date、expiration_date])
模拟器 ([id], 名称)
其中 pilot_id 指的是... blablabla。
方括号定义了每个实体的主键。
3。我该如何回答这些问题?
- 哪些飞行员不能进入他们通过编队的模拟器?
- 在x个月通过编队的模拟器中,哪些飞行员会不适应,不包括那些已经不适应的飞行员?
我等待的输出如下所示:
+------------------------------------------------+
| Inapt pilots |
+------------+-----------------+-----------------+
| First name | Last name | Simulator |
+------------+-----------------+-----------------+
| John | Doe | Falcon 7X |
| John | Doe | Embraer ERJ 140 |
| Foo | Bar | Falcon 20 |
+------------+-----------------+-----------------+
为每个不称职的飞行员提供他不能去的模拟器。
首先,评论:您不需要 IS_TRAINED_FOR
table 中的到期日期。飞行员和模拟器 ID 加上采集日期就足够了。
回答您的问题:
是的,您的数据模型可用于所述目的。
除了我上面的评论,你的 table 定义没问题。
您要求的查询看起来像这样:
-- Get pilots that are no longer qualified for a simulator that they
-- have previously qualified for...
select distinct
P.first_name
, P.last_name
, S.name
from PILOT P
inner join IS_TRAINED_FOR T
on P.id = T.pilot_id
inner join SIMULATOR S
on T.simulator_id = S.id
where NOT EXISTS (select Q.acquisition_date
from IS_TRAINED_FOR Q
where Q.acquisition_date <= NOW()
and Q.expiration_date >= NOW()
and Q.pilot_id = T.pilot_id
and Q.simulator_id = T.simulator_id)
因为上面的查询使用了内连接,所以只会显示曾经获得模拟器资格的飞行员,但是因为WHERE子句,只有在他们的资格过期时才会显示。
请注意,使用相关子查询是因为如果飞行员的资格已过期但后来被更新(并且仍然有效),那么简单地说诸如到期日期小于 NOW() 之类的内容将失败。
要查看谁将在 X 个月内被取消资格,只需将 X 个月添加到上述查询中的 NOW() 中,如下所示:(对于此示例,假设 4 个月...)
DATE_ADD(NOW(),INTERVAL 4 MONTH)
要查看从现在到 x 个月后谁将被取消资格,请使用此查询:
-- Get pilots whose qualifications will be expiring for a simulator that they
-- are currently qualified for...
select distinct
P.first_name
, P.last_name
, S.name
from PILOT P
inner join IS_TRAINED_FOR T
on P.id = T.pilot_id
inner join SIMULATOR S
on T.simulator_id = S.id
where NOT EXISTS (select Q.acquisition_date
from IS_TRAINED_FOR Q
where Q.acquisition_date <= DATE_ADD(NOW(),INTERVAL 4 MONTH)
and Q.expiration_date >= DATE_ADD(NOW(),INTERVAL 4 MONTH)
and Q.pilot_id = T.pilot_id
and Q.simulator_id = T.simulator_id)
and T.acquisition_date <= NOW()
and T.expiration_date >= NOW()
and T.expiration_date <= DATE_ADD(NOW(),INTERVAL 4 MONTH
第二个查询显示在 4 个月内(例如)不合格并且他们现在合格的飞行员。