写在前面
这篇文章主要以几个作者做过的关系数据库练习题为主,多在SQL语言上以伪代码的方式实现,为各位分享一下学习的经验,如有不足,还请多多指教
一、题目描述
有一个图书馆管理数据库,分别为表名以及列名,信息如下
- 读者(读者编号,姓名,单位)
- 图书(书号,书名,作者,出版社,单价,类型)
- 借阅记录(读者编号,书号,借阅日期,应还日期)
- 还书记录(读者编号,书号,归还日期)
有查询要求如下
- 查询"人民邮电出版社"出版的所有图书的相关信息
- 查询单价在15元以上的书名和作者
- 查询8号读者2017年3月10日所借的图书的相关信息
- 查询超期归还图书的读者姓名和单位
- 查询借阅过《天龙八部》的读者的信息
- 查询借阅过“金庸”所有著作的读者的姓名
- 查询没有借阅过任何图书的读者的姓名
二、习题解答
1.关系代数解答
-
查询"人民邮电出版社"出版的所有图书的相关信息
σ 出版社 = 人民邮电 ( 图书 ) \sigma _{\text{出版社}=\text{人民邮电}}\left( \text{图书} \right) σ出版社=人民邮电(图书) -
查询单价在15元以上的书名和作者
Π 书名,作者 ( σ 单价 > 15 元 ( 图书 ) ) \varPi _{\text{书名,作者}}\left( \sigma _{\text{单价}>15\text{元}}\left( \text{图书} \right) \right) Π书名,作者(σ单价>15元(图书)) -
查询8号读者2017年3月10日所借的图书的相关信息
Π 书号 ( σ 读者编号 = 8 ( 读者 ) ∧ σ 借阅日期 = 20170310 ( 借阅记录 ) ) ⋈ ( 图书 ) \varPi _{\text{书号}}\left( \sigma _{\text{读者编号}=8}\left( \text{读者} \right) \land \sigma _{\text{借阅日期}=20170310}\left( \text{借阅记录} \right) \right)\bowtie \left( \text{图书} \right) Π书号(σ读者编号=8(读者)∧σ借阅日期=20170310(借阅记录))⋈(图书) -
查询超期归还图书的读者姓名和单位
注意: 这个题目十分具有迷惑性,如果直接将借阅记录和还书记录两个表直接作(归还日期>应还日期)条件下的
θ
\theta
θ连接是不可取的,因为DBMS有可能是读取两个不同读者的归还日期和应还日期,所以应当将两个表进行等值连接后再判断
Π
姓名
(
σ
归还日期
>
应还日期
(
(
借阅记录
)
⋈
(
还书记录
)
)
⋈
(
读者
)
)
\varPi _{\text{姓名}}\left( \sigma _{\text{归还日期}>\text{应还日期}}\left( \left( \text{借阅记录} \right) \bowtie \left( \text{还书记录} \right) \right) \bowtie \left( \text{读者} \right) \right)
Π姓名(σ归还日期>应还日期((借阅记录)⋈(还书记录))⋈(读者))
- 查询借阅过《天龙八部》的读者的信息
Π 读者编号 ( σ 书名 = 《天龙八部》 ( 图书 ) ⋈ ( 借阅记录 ) ) ⋈ ( 读者 ) \varPi _{\text{读者编号}}\left( \sigma _{\text{书名}=\text{《天龙八部》}}\left( \text{图书} \right) \bowtie \left( \text{借阅记录} \right) \right) \bowtie \left( \text{读者} \right) Π读者编号(σ书名=《天龙八部》(图书)⋈(借阅记录))⋈(读者) - 查询借阅过“金庸”所有著作的读者的姓名
Π 读者姓名 ( ( Π 读者编号 , 书号 ( 借阅记录 ) ÷ σ 作者 = “ 金庸 ” ( 图书 ) ) ⋈ ( 读者 ) ) \varPi _{\text{读者姓名}}\left( \left( \varPi _{\text{读者编号},\text{书号}}\left( \text{借阅记录} \right) \div \sigma _{\text{作者}=“\text{金庸}”}\left( \text{图书} \right) \right) \bowtie \left( \text{读者} \right) \right) Π读者姓名((Π读者编号,书号(借阅记录)÷σ作者=“金庸”(图书))⋈(读者)) - 查询没有借阅过任何图书的读者的姓名
Π 姓名 ( ( Π 读者编号 ( 读者 ) − Π 读者编号 ( 借阅记录 ) ) ⋈ ( 读者 ) ) \varPi _{\text{姓名}}\left( \left( \varPi _{\text{读者编号}}\left( \text{读者} \right) -\varPi _{\text{读者编号}}\left( \text{借阅记录} \right) \right) \bowtie \left( \text{读者} \right) \right) Π姓名((Π读者编号(读者)−Π读者编号(借阅记录))⋈(读者))
2.使用带where选择条件的SQL语句解答
代码如下(示例):
1.查询8号读者2017年3月10日所借的图书的相关信息
SELECT 图书.*
FROM 图书,借阅记录
WHERE 图书.书号 = 借阅记录.书号 and 读者编号 = '8' and 借阅日期 = '20170310'
2.查询超期归还图书的读者姓名和单位
SELECT 借阅记录.读者号
FROM 借阅记录,还书记录
WHERE 借阅记录.书号 = 还书记录.书号 and 借阅记录.读者编号 = 还书记录.读者号 and 归还日期 > 应还日期
3. 查询借阅过《天龙八部》的读者的信息
SELECT 读者.*
FROM 读者,图书,借阅记录
WHERE 读者.读者号 = 借阅记录.读者号 and 图书.书号 = 借阅记录.书号 and 书名 = '《天龙八部》'
3.嵌套式查询描述SQL
1.查询8号读者2017年3月10日所借的图书的相关信息
S
o
l
u
t
i
o
n
1
\color{#FF3030}{Solution1}
Solution1
SELECT *
FROM 图书
WHERE 书号 in (
SELECT 书号
FROM 借阅记录
WHERE 借阅日期 = '20170310' and 读者编号 = 8)
S o l u t i o n 2 ( 带 e x i s t s ) \color{#FF3030}{Solution2(带exists)} Solution2(带exists)
SELECT *
FROM 图书
WHERE EXISTS(
SELECT *
FROM 借阅记录
WHERE 书号 = 图书.书号 and 读者编号 = '8' and 借阅日期 = '20170310')
2.查询超期归还图书的读者姓名和单位
SELECT 姓名,单位
FROM 读者
WHERE 读者 in (
SELECT 借阅记录,读者编号
FROM 借阅记录,还书记录
WHERE借阅记录.读者号 = 还书记录.读者号 and 借阅记录.书号 = 还书记录.书号 and 应还日期 < 归还日期)
3. 查询借阅过《天龙八部》的读者的信息
S
o
l
u
t
i
o
n
1
\color{#FF3030}{Solution1}
Solution1
SELECT *
FROM 读者
WHERE 读者编号 in (
SELECT 读者编号
FROM 借阅记录
WHERE 书号 = (
SELECT 书号
FROM 图书
WHERE 书名 = '《天龙八部》')
)
S o l u t i o n 2 ( 带 e x i s t s ) \color{#FF3030}{Solution2(带exists)} Solution2(带exists)
SELECT *
FROM 读者
WHERE EXISTS(
SELECT *
FROM 借阅记录
WHERE 读者编号 = 读者.读者编号 and EXISTS(
SELECT *
FORM 图书
WHERE 书号 = 借阅记录.书号 and 书名 = '《天龙八部》')
)
4.查询借阅过“金庸”所有著作的读者的姓名
SELECT 姓名
FROM 读者
WHERE not EXISTS(
SELECT *
FROM 图书(怎样的书?)
WHERE 作者 = '金庸' and not EXISTS(
SELECT *
FROM 借阅记录
WHERE 读者号 = 读者.读者号 and 书号 = 图书.书号
)
)
5.查询没有借阅过任何图书的读者的姓名
S
o
l
u
t
i
o
n
1
\color{#FF3030}{Solution1}
Solution1
SELECT 姓名
FROM 读者
WHERE 读者编号 not in (
SELECT 读者编号
FROM 借阅记录
WHERE 读者编号 = 读者.读者编号
)
S o l u t i o n 2 ( 带 e x i s t s ) \color{#FF3030}{Solution2(带exists)} Solution2(带exists)
SELECT 姓名
FROM 读者
WHERE 读者编号 not EXISTS(
SELECT *
FROM 借阅记录
WHERE 读者编号 = 读者.读者编号
)
写在最后
本文作者才疏学浅,若有纰漏,恳请斧正
本文章仅用于各位同志作为学习交流之用,不作任何商业用途,若涉及版权问题请与作者联系,望悉知