數據庫實驗二 數據查詢

一、實驗目的
(1)掌握查詢語句的一般格式;
(2)熟練掌握單表查詢、連接查詢、集合查詢、統計查詢和嵌套查詢。
二、實驗環境
PLSQL Developer 12
Oracle Database 11 home
三、實驗步驟、出現的問題及解決方案
實驗步驟:
1、查詢“紅樓夢”目前可借的各圖書編號,及所屬版本信息。(是否借出爲‘否‘的圖書)
SELECT 圖書.圖書編號,書目.ISBN,書目.書名,書目.作者,書目.出版單位
FROM 書目,圖書
WHERE 書目.ISBN=圖書.ISBN AND 書目.書名=‘紅樓夢’ AND 是否借出=‘否’;
在這裏插入圖片描述
2、查找高等教育出版社的所有書目及單價,結果按單價降序排序。
SELECT *
FROM 書目
WHERE 出版單位=‘高等教育出版社’
ORDER BY 單價 DESC;
在這裏插入圖片描述
3、統計“紅樓夢”各版的藏書數量(ISBN不同則版本不同)。
SELECT 書目.ISBN,COUNT(書目.ISBN)
FROM 書目,圖書
WHERE 書目.ISBN=圖書.ISBN AND 書目.書名=‘紅樓夢’
GROUP BY 書目.ISBN;
在這裏插入圖片描述
4、查詢學號“20061234”號借書證借閱未還的圖書的信息。
SELECT 書目.*
FROM 書目,圖書,借閱
WHERE 書目.ISBN=圖書.ISBN AND 圖書.圖書編號=借閱.圖書編號 AND 借閱.借書證號=‘20061234’;
在這裏插入圖片描述
5、查詢各個出版社的圖書最高單價、平均單價。
SELECT 書目.出版單位,MAX(單價),AVG(單價)
FROM 書目,圖書
WHERE 書目.ISBN=圖書.ISBN
GROUP BY 書目.出版單位;
在這裏插入圖片描述
6、要查詢借閱了兩本和兩本以上圖書的讀者的個人信息。
SELECT 讀者.*
FROM 讀者
WHERE 讀者.借書證號 IN
(
SELECT 借閱.借書證號
FROM 讀者,借閱
WHERE 讀者.借書證號=借閱.借書證號
GROUP BY 借閱.借書證號
HAVING COUNT()>=2
);
在這裏插入圖片描述
7、查詢“王菲”的單位、所借圖書的書名和借閱日期。
SELECT 書目.書名,借閱.借書日期
FROM 書目,圖書,借閱
WHERE 書目.ISBN=圖書.ISBN AND 圖書.圖書編號=借閱.圖書編號 AND 借閱.借書證號 IN
(
SELECT 讀者.借書證號
FROM 讀者
WHERE 讀者.單位=
(
SELECT 讀者.單位
FROM 讀者
WHERE 讀者.姓名=‘王菲’
)
);
在這裏插入圖片描述
8、查詢每類圖書的冊數和平均單價。
SELECT 圖書分類.類名,COUNT(
),AVG(單價)
FROM 圖書分類,書目,圖書
WHERE 圖書分類.圖書分類號=書目.圖書分類號 AND 書目.ISBN=圖書.ISBN
GROUP BY 圖書分類.類名;
在這裏插入圖片描述
9、統計從未借書的讀者人數。
SELECT COUNT()
FROM 讀者
WHERE 讀者.借書證號 NOT IN
(
SELECT 借閱.借書證號
FROM 借閱
);
在這裏插入圖片描述
10、統計參與借書的人數。
SELECT COUNT(
)
FROM 讀者
WHERE 讀者.借書證號 IN
(
SELECT 借閱.借書證號
FROM 借閱
);
在這裏插入圖片描述
11、找出所有借書未還的讀者的信息及所借圖書編號及名稱。
SELECT 讀者.,圖書.圖書編號,書目.書名
FROM 讀者,圖書,書目,借閱
WHERE 圖書.ISBN=書目.ISBN AND 借閱.圖書編號=圖書.圖書編號 AND 借閱.借書證號=讀者.借書證號 AND 借閱.歸還日期 IS NULL;
在這裏插入圖片描述
12、檢索書名是以“Internet”開頭的所有圖書的書名和作者。
SELECT 書目.書名,書目.作者
FROM 書目
WHERE REGEXP_LIKE(書目.書名,’^Internet’);
在這裏插入圖片描述
13、查詢各圖書的罰款總數。
SELECT 圖書.圖書編號,罰款.罰款總數
FROM 圖書
LEFT JOIN
(
SELECT 借閱.圖書編號,SUM(罰款分類.罰金) AS 罰款總數
FROM 借閱,罰款分類
WHERE 罰款分類.罰款分類號=借閱.罰款分類號
GROUP BY 借閱.圖書編號
) 罰款
ON 罰款.圖書編號=圖書.圖書編號;
在這裏插入圖片描述
14、查詢借閱及罰款分類信息,如果有罰款則顯示借閱信息及罰款名稱、罰金,如果沒有罰款則罰款名稱、罰金顯示空(左外連接)
SELECT 借閱.
,罰款分類.罰款名稱,罰款分類.罰金
FROM 借閱
LEFT JOIN 罰款分類
ON 罰款分類.罰款分類號=借閱.罰款分類號;
在這裏插入圖片描述
15、查詢借閱了所有“文學”類書目的讀者的姓名、單位。
(1)方法一,雙重否定表肯定,查詢的讀者不存在文學類的書沒有借過
SELECT 讀者.姓名,讀者.單位
FROM 讀者
WHERE NOT EXISTS
(
SELECT * FROM 圖書分類,書目
WHERE 圖書分類.圖書分類號=書目.圖書分類號 AND 圖書分類.類名=‘文學’ AND NOT EXISTS
(
SELECT *
FROM 借閱,圖書
WHERE 借閱.圖書編號=圖書.圖書編號 AND 借閱.借書證號=讀者.借書證號 AND 書目.ISBN=圖書.ISBN
)
);
在這裏插入圖片描述
(2)方法二,查詢的讀者借的文學類書的數目(去重同一借書證借同一ISBN的文學書後的數目)等於文學類書的數目
SELECT 讀者.姓名,讀者.單位
FROM 讀者
WHERE 讀者.借書證號 IN
(
SELECT 讀者文學類借書.借書證號
FROM
(
SELECT 文學借書數.借書證號,COUNT() AS 讀者文學類數借書數
FROM
(
SELECT 借閱.借書證號,圖書.ISBN
FROM 借閱,圖書分類,書目,圖書
WHERE 借閱.圖書編號=圖書.圖書編號 AND 圖書.ISBN=書目.ISBN AND 書目.圖書分類號=圖書分類.圖書分類號 AND 圖書分類.類名=‘文學’
GROUP BY (借閱.借書證號,圖書.ISBN)
) 文學借書數
GROUP BY 文學借書數.借書證號
) 讀者文學類借書,
(
SELECT COUNT(
) AS 總數
FROM 圖書分類,書目
WHERE 圖書分類.圖書分類號=書目.圖書分類號 AND 圖書分類.類名=‘文學’
) 文學類書總數
WHERE 讀者文學類借書.讀者文學類數借書數=文學類書總數.總數
);
在這裏插入圖片描述
擴展:
1、在書目關係中新增“出版年份”,並在該屬性下添加數據。
在這裏插入圖片描述

ALTER TABLE 書目 ADD 出版年份 VARCHAR(100);
UPDATE 書目 SET 出版年份=‘2005’ WHERE ISBN=‘7040195836’;
UPDATE 書目 SET 出版年份=‘1983’ WHERE ISBN=‘9787508040110’;
UPDATE 書目 SET 出版年份=‘2008’ WHERE ISBN=‘9787506336239’;
UPDATE 書目 SET 出版年份=‘2009’ WHERE ISBN=‘9787010073750’;
COMMIT;在這裏插入圖片描述
2、求總藏書量、藏書總金額、最高價、最低價。
SELECT COUNT(),SUM(單價),MAX(單價),MIN(單價)
FROM 書目,圖書
WHERE 書目.ISBN=圖書.ISBN;
在這裏插入圖片描述
3、列出藏書在5本以上的書目(書名、作者、出版社、出版年份)。
SELECT 書目.書名,書目.作者,書目.出版單位,書目.出版年份
FROM 書目
WHERE 書目.ISBN IN
(
SELECT 書目.ISBN
FROM 書目,圖書
WHERE 書目.ISBN=圖書.ISBN
GROUP BY 書目.ISBN
HAVING COUNT(
)>5
);
在這裏插入圖片描述
4、列出年份最久遠的書?
SELECT *
FROM 書目
WHERE 書目.出版年份=
(
SELECT MAX(出版年份)
FROM 書目
);
在這裏插入圖片描述
5、 目前實際已借出多少冊書?
SELECT COUNT()
FROM 圖書
WHERE 圖書.是否借出=‘是’;
在這裏插入圖片描述
6.、哪一年的圖書最多?
SELECT 年份.出版年份
FROM
(
SELECT 書目.出版年份,COUNT(書目.出版年份) AS NUM
FROM 書目,圖書
WHERE 書目.ISBN=圖書.ISBN
GROUP BY 書目.出版年份
) 年份,
(
SELECT MAX(COUNT(
)) AS MAX
FROM 書目,圖書
WHERE 書目.ISBN=圖書.ISBN
GROUP BY 書目.出版年份
) 最多
WHERE 年份.NUM=最多.MAX;
在這裏插入圖片描述
7、 哪本借書證未歸還的圖書最多?
SELECT 統計.借書證號
FROM
(
SELECT MAX(COUNT(借閱.借書證號)) AS MAX
FROM 借閱
WHERE 借閱.歸還日期 IS NULL
GROUP BY 借閱.借書證號
) 最多,
(
SELECT 借閱.借書證號,COUNT(借閱.借書證號) AS NUM
FROM 借閱
WHERE 借閱.歸還日期 IS NULL
GROUP BY 借閱.借書證號
) 統計
WHERE 統計.NUM=最多.MAX;
在這裏插入圖片描述
8、平均每本借書證的借書冊數。
SELECT SUM(借閱數.借閱_NUM/讀者數.讀者_NUM)
FROM
(
SELECT COUNT() AS 借閱_NUM
FROM 借閱
) 借閱數,
(
SELECT COUNT(
) AS 讀者_NUM
FROM 讀者
) 讀者數;
在這裏插入圖片描述
9、哪個單位的讀者平均借書冊數最多?
SELECT 單位平均數.單位
FROM
(
SELECT 讀者單位人數.單位,SUM(讀者單位借書數.借書數/讀者單位人數.人數) AS 平均數
FROM
(
SELECT 讀者.單位,COUNT() AS 人數
FROM 讀者
GROUP BY 讀者.單位
) 讀者單位人數,
(
SELECT 讀者.單位,COUNT(
) AS 借書數
FROM 讀者,借閱
WHERE 讀者.借書證號=借閱.借書證號
GROUP BY 讀者.單位
) 讀者單位借書數
WHERE 讀者單位人數.單位=讀者單位借書數.單位
GROUP BY 讀者單位人數.單位
) 單位平均數,
(
SELECT MAX(SUM(讀者單位借書數.借書數/讀者單位人數.人數)) AS 借書數
FROM
(
SELECT 讀者.單位,COUNT() AS 人數
FROM 讀者
GROUP BY 讀者.單位
) 讀者單位人數,
(
SELECT 讀者.單位,COUNT(
) AS 借書數
FROM 讀者,借閱
WHERE 讀者.借書證號=借閱.借書證號
GROUP BY 讀者.單位
) 讀者單位借書數
WHERE 讀者單位人數.單位=讀者單位借書數.單位
GROUP BY 讀者單位人數.單位
) 單位最多借書數
WHERE 單位平均數.平均數=單位最多借書數.借書數;
在這裏插入圖片描述
10、 最近兩年都未被借過的書。
SELECT 圖書.圖書編號
FROM 圖書
WHERE 圖書.圖書編號 NOT IN
(
SELECT 借閱.圖書編號
FROM 借閱
WHERE MONTHS_BETWEEN(SYSDATE,借閱.借書日期)/12<=2
);
在這裏插入圖片描述
11、今年未借過書的借書證。
SELECT 讀者.借書證號
FROM 讀者
WHERE 讀者.借書證號 NOT IN
(
SELECT 借閱.借書證號
FROM 借閱
WHERE 借閱.借書日期>
(
SELECT TRUNC(SYSDATE,‘YYYY’) FROM DUAL
)
);
在這裏插入圖片描述
出現的問題及解決方案:
1、無法調用派生表及聚集函數的列,解決方案:使用派生表中的列,需要給派生表取別名,才能在WHERE語句中調用,調用方法:別名.列名,如果子查詢結果中使用了聚集函數,需要給聚集函數這列取別名,才能調用,調用時使用別名。表取別名不能用AS。
2、對15題,查詢借閱了所有“文學”類書目的讀者的姓名、單位,產生了錯誤的理解,題目的意思是查詢到的讀者要借閱了所有的文學類書,而不是借閱了文學類的書的讀者有哪些,解決方案:
(1)方法一,雙重否定表肯定,查詢的讀者不存在文學類的書沒有借過
SELECT 讀者.姓名,讀者.單位
FROM 讀者
WHERE NOT EXISTS
(
SELECT *
FROM 圖書分類,書目
WHERE 圖書分類.圖書分類號=書目.圖書分類號 AND 圖書分類.類名=‘文學’ AND NOT EXISTS
(
SELECT *
FROM 借閱,圖書
WHERE 借閱.圖書編號=圖書.圖書編號 AND 借閱.借書證號=讀者.借書證號 AND 書目.ISBN=圖書.ISBN
)
);
(2)方法二,查詢的讀者借的文學類書的數目(去重同一借書證借同一ISBN的文學書後的數目)等於文學類書的數目
SELECT 讀者.姓名,讀者.單位
FROM 讀者
WHERE 讀者.借書證號 IN
(
SELECT 讀者文學類借書.借書證號
FROM
(
SELECT 文學借書數.借書證號,COUNT() AS 讀者文學類數借書數
FROM
(
SELECT 借閱.借書證號,圖書.ISBN
FROM 借閱,圖書分類,書目,圖書
WHERE 借閱.圖書編號=圖書.圖書編號 AND 圖書.ISBN=書目.ISBN AND 書目.圖書分類號=圖書分類.圖書分類號 AND 圖書分類.類名=‘文學’
GROUP BY (借閱.借書證號,圖書.ISBN)
) 文學借書數
GROUP BY 文學借書數.借書證號
) 讀者文學類借書,
(
SELECT COUNT(
) AS 總數
FROM 圖書分類,書目
WHERE 圖書分類.圖書分類號=書目.圖書分類號 AND 圖書分類.類名=‘文學’
) 文學類書總數
WHERE 讀者文學類借書.讀者文學類數借書數=文學類書總數.總數
);
3、ORACLE不支持使用DATEDIFF()函數計算時間差,解決方案:使用MONTHS_BETWEEN()方法來計算兩個日期的月份之差,然後除以12,得到年份之差,就可以查詢最近兩年都未被借過的書了,MONTHS_BETWEEN()函數中的參數不能顛倒,否則會爲負數。
4、怎麼獲取今年的第一天的日期?解決方案:使用TRUNC()函數將使用SYSDATE查詢的日期從年份截去,就可以獲取今年的第一天的日期,SELECT TRUNC(SYSDATE,‘YYYY’) FROM DUAL。
四、實驗心得體會
通過本次實驗熟練的掌握了查詢的基本用法,對查詢的嵌套有了更加深刻直觀的認識,通過實驗練習了一些難度較大的查詢,對查詢設計的思路更加清晰,知道該如何嵌套使用子查詢以及怎樣查詢更清晰,不過也認識到了自己的不足,如15題,對於相關子查詢掌握還不夠好,思路不夠清晰,理解不夠透徹。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章