數據庫第一次作業(第三章)


數據庫第一次作業

3.1 使用大學模式,用SQL寫出如下查詢。

a.找出Comp.Sci系開設的具有三個學分的課程名稱。

	select title
 	  from course
	 where dept_name = 'Comp. Sci.' and course.credits = 3;

b. 找出名叫Einstein的教師所教的所有學生的標識,保證結果中沒有重復。

	select distinct takes.id
  	  from instructor natural join teaches 
	       join takes using (course_id,sec_id,semester,year)
 	 where name = 'Einstein'; 

c. 找出教師的最高工資

	select max(salary) 
	  from instructor

d. 找出工資最高的所有教師

	select name 
	from   instructor
	where salary=(select Max(salary) from instructor)

e.找出2009年秋季開設的每個課程段的選課人數

	select course_id, sec_id, count(ID) 
	from   section natural join takes 
	where semester = 'Fall' and year = 2009 
	group by course_id, sec_id

f.從2009年秋季開設的每個課程段中,找出最多的選課人數

	select Max(cnt) 
	from ( 
		select Count(ID) as cnt
		from   section natural join takes 
		where semester = 'Fall' and year = 2009 group by course_id, sec_id 
	)

g.找出在2009年秋季擁有最多選課人數的課程段。

	with Fall2009 as (
	  	select course_id, sec_id, count(ID) as cnt
	  	from   section natural join takes 
	 	where  semester = 'Fall' and year = 2009 
	  	group  by course_id, sec_id
	)

	select course_id,sec_id
	from   Fall2009
	where cnt  = (select max(cnt) from Fall2009)

3.2 假設給你一個關系grade_points(grad_e,points),他提供從takes關系中用字母表示的成績等級到數字表示的得分之間的轉換。例如,“A”等級可指定為對應於4分,“A-”對應於3.7分,“B+”對應於3.3分,“B”對應於3分,等等。學生在某門課程(課程段)上所獲取的等級分值被定義為該課程段的學分乘以該生得到的成績等級所對應的數字表示的得分。

/根據題意創建表/

	/*創建表關系*/
	create table Grade_points
	(
	   grade  varchar (2),
	   Points  numeric(3, 1)
	);


	/*插入值*/
	insert into grade_points values ('A',4.0);
	insert into grade_points values ('A-',3.7);
	insert into grade_points values ('B+',3.3);
	insert into grade_points values ('B',3.0);
	insert into grade_points values ('B-',2.7);
	insert into grade_points values ('C+',2.3);
	insert into grade_points values ('C',2.0);
	insert into grade_points values ('C-',1.7);

a.根據ID為12345的學生所選修的所有課程,找出該生所獲得等級分值的總和。

	select distinct sum(credits * points) 
	  from takes natural join course natural join grade_points
	 where ID = 12345;

b. 找出上述學生等級分值的平均值(GPA),即用改等級分值的總和除以相關課程學分的總和。

	select distinct sum(credits * points) /sum(credits) AS res
	  from takes natural join course natural join grade_points
	 where ID = 12345;

c.找出每個學生的ID和等級分值得平均值

	select distinct sum(credits * points) /sum(credits) AS GPA
	  from takes natural join course natural join grade_points
	 group by ID;

3.3 使用大學模式,用SQL寫出如下出入、刪除和更新語句。

a.給 Comp.Sci 系老師漲10%的工資。

	update instructor
	   set instructor.salary = instructor.salary * 1.10
	 where instructor.dept_name = 'Comp. Sci.';

b.刪除所有未開設過的課程。

	delete from course
	 where course_id not in (select distinct course_id from section);

c.把每一個在tot_cread屬性上取值超過100的學生作為同系的教師插入,工資為10000美元。

	insert into instructor
	select ID,name,dept_name,10000
	  from student
	 where tot_cred >= 100;

3.4 考慮圖3-18中的保險公司數據,其中加下划線的是主碼,為這個數據庫構造出如下SQL查詢。

	person( driver_id, name, address)
	ar( license, model, year)
	ccident( report_number, date, location)
	wns (driver_id, license)
	artcipated ( report_number, license, driver_id, damage_amount)

a.找出2009年其車輛出現過交通事故的人員總數。

	select count(distinct driver_id) AS num_of_person
  	  from person natural join participated natural join accident
     where date between date ’1989-00-00’ and date ’1989-12-31’ 

b.向數據庫中增加一個新的事故,對每個必須的屬性可以設定任意值。

	insert into accident
	values (1239401,'1991-01-01','Wl');

c.刪除“John Smith”擁有的馬自達車(Mazda)。

	delete frrm car 
	 where Model = 'Mazda' and license in (
		   select license 
		   from person p, owns o 
		   where p.name = ’John Smith’ and p.driver id = o.driver id
	 );

3.5 假設有關系marks(ID, score), 我們希望基於如下標准為學生評定等級:如果 score < 40 得 F; 如果 40 <= score < 60 得 C; 如果 60 <= score < 80 得 B;如果 80 <= score 得A。 寫出SQL查詢完成下列操作。

a.基於marks關系顯示每個學生的等級。

	select ID,
		   case 
			   when score < 40 then 'F'
			   when score < 60 then 'C'
			   when score < 80 then 'B'
			   else 'A'
		   end 
			   as rank
	from marks;

b.找出各等級的學生數

	select count(ID) as cnt 
	from
	(
		select ID,
			   case 
				   when score < 40 then 'F'
				   when score < 60 then 'C'
				   when score < 80 then 'B'
				   else 'A'
			   end 
				   as rank
		from marks;
	)group  by rank;

3.6 SQL的like運算符是大小寫敏感的,但字符串上的lower()函數可用來實現大小寫不敏感的匹配。為了說明是怎么實現的,寫出這樣一個插敘:找出名稱中包含了“sci”子串的系, 忽略大小寫。

	select dept_name
	  from department
	 where lower(dept_name) like '%sci%';

3.7 考慮以下SQL查詢在什么條件下這個查詢選擇的p.al值要么在r1中,要么在r2中?仔細考察r1或r2位空的情況。

	select distinct p.al
	  from p,r1,r2
	 where p.al = r1.al or p.a1 = r2.al;
解:  當且僅當r1,r2非空時,p.a1要么在r1中要么在r2中。
	 當r1或r2空時,r1 X  r2為空。
     當p是空時,顯然查詢結果是為空的正解

3.8 考慮圖3-19中的銀行數據庫,期中加下划線的是主碼。為這個關系數據庫構造出如下SQL查詢:

銀行數據庫
branch(branch name, branch city, assets)
customer (customer name, customer street, customer city)
loan (loan number, branch name, amount)
borrower (customer name, loan number)
account (account number, branch name, balance )
depositor (customer name, account number)

a.找出銀行中所有有賬號但無貸款的客戶

	(select customer_name from desositor)
	from 
	(select customer_name from borrower)

b.找出與Smith居住在同一城市、同一接到的所有客戶的名字

	select F.customer_name
	  from customer F join customer S using (customer_street,customer_city)
	 where S.customer_name = 'Smith';

c.找出所有支行的名稱,在這些支行中都有居住在Harrison的客戶所開的賬戶

	select branch_name
	  from acoount natural join depositor natural join customer
	 where branch_city = 'Harrison';

3.9 考慮圖3.20的雇員數據庫,其中加下划線的是主碼。為下面每個查詢寫出SQL表達式:

	圖3.20 雇員數據庫
	employee (employee name, street, city)
	works (employee name, company name, salary)
	company (company name, city)
	manages (employee name, manager name)

a.找出所有為First Bank Corporation工作的雇員機器居住城市。

	select employee_name,city
	  from employee
	 where employee_name in (
		   select employee_name 
			 from works 
			where company_name = 'First Bank Corporation'
	 );

b.找出所有為First Bank Corporation工作且薪金超過10000美元的雇員名字、居住的接到和城市。

	select employee_name,street,city
	  from employee natural join works
	 where company_name = 'First Bank Corporation' and salary > 10000;

c.找出數據庫中所有不為First Bank Corporation工作的雇員。

	select employee_name
	  from works
	 where employee_name not in (
		   select employee_name
			 from works
			where company_name = 'First Bank Corporation'
		   );

d.找出數據庫中所有工資不高於Small Bank Corporation

	select employee_name
	  from works
	 where salary > (
		   select max(salary)
			 from works
			where company_name = 'Small Bank Corporation'
		   );

e. 假設一個公司可以在好幾個城市有分部。找出位於Small Bank Corporation所在城市的所有公司。

	select C.company_name
	  from company C join company P using (city) 
	 where P.company_name = 'Small Bank Corporation';

f.找出雇員最多的公司

	select company_name
	  from works
	 group by company_name
	having count (distinct employee_name) >=
				all(  select count (distinct  Employee_name)
						from works
					   group by company_name);l

g.找出平均工資高於First Bank Corporation的那些公司。

	select company_name
	  from works
	 group by company_name
	having avg(salary) > (
		   select avg(salary)
			 from works
			where company_name = 'First Bank Name');

3.10 考慮圖3.20的關系數據庫,給出下面每個查詢的sql表達式:

a. 修改數據庫使John現在居住在Newton。

	update employee 
	   set city = 'Newtown'
	 where employee_name = 'Johns';

b. 為First Bank Corporation所有工資不超過100000美元的經理增長10%的工資,對工資超過100000美元的只增長3%。

	update works
	   set salary = 
		   case
			   when salary * 1.10 <= 100000 then salary * 1.10
			   else salary * 1.03
		   end
	 where company_name = 'First Bank Corporation' and employee_name in (select employee_name from managers);

3.11 使用大學模式,用SQL寫出如下查詢。

a.找出至少選修了一門Comp. Sci. 課程的學生姓名,保證結果中沒有重復的姓名

	select distinct student.name
	  from student natural join takes join course using (course_id)
	 where course.dept_name = 'Comp. Sci.';

b.找出所有沒有選修在2009年春季之前開設的任何課程的學生的ID和姓名。

	select distinct ID,name
	  from student
	 where id not in((select distinct ID
						from takes
					   where year < 2009 or(year = 2009 and semester ='Spring')));

c.找出每個系教師的最高工資。可以假設每個系至少有一位老師。

	select dept_name,max(salary)
	  from instructor
	 group by dept_name;

d.從前述查詢所計算出的每個系最高工資中選出最低值。

	select min(MAX_SALARY)
	  from(select dept_name,max(salary) as MAX_SALARY
			 from instructor
			group by dept_name);

3.12 使用大學模式,用SQL寫出如下查詢。

a.創建按一門課程CS- 001,其名稱為Weekly Seminar,學分為0。

	insert into course values
				('CS-001',
				 'Weekly Seminar',
				 '',
				 0);

b.創建該課程在2009年秋季的一個課程段,sec_id 為1。

	insert into section
		 values ('CS - 001',
				 1,
				 'Fall',
				 2009,
				 NULL,
				 NULL,
				 NULL);

c.讓Comp. Sic.系的每一個學生都選修上述課程段。

	insert into takes 
		   select ID, 
				  'CS - 001',
				  1,
				  'Fall',
				  2009,
				  NULL
			 from student
			where Dept_name = 'Comp. Sci.';

d. 刪除名為Chavez的學生選修上述課程段的信息。

	delete from takes 
	 where course_id = 'CS-001'
	   and sec_id = 1
	   and year = 2009
	   and semester = 'Fall'
	   and ID in(
			   select ID 
				 from student 
				where name = 'Chavez'
				);

e.刪除課程CS - 001如果在運行此刪除語句之前,沒有先刪除這門課程的授課信息(課程段),會發生什么事情。

	delete from course
	 where course_id = 'CS-001';
	如果在刪除語句之前,沒有先刪除課程段,則其對應課程段和學生的選課信息一起被刪。因為在建表的DDL語句中加入了級聯刪除的設置。

f.刪除課程名稱中包含datebase的任意課程的任意課程段所對應的所有take元組,在課程名的匹配中忽略大小寫。

	delete from takes
	 where course_id not in (select course_id
							   from course
							  where lower(title) like '%database%');

3.13寫出圖3-18中模式的SQL DDL。在數據類型上做合理的假設,確保申明主碼和外碼。

	create table person
	(
		 driver_id   varchar(50),
		 name        varchar(50),
		 address     varchar(50),
		 primary key(driver_id)
	);

	create table car
	(
		 license     varchar(50),
		 model       varchar(50),
		 year        numeric(5,0),
		 primary key (license)
	);

	create table accident
	(
		 report_number varchar(10),
		 dateion       date,
		 loaction      varchar(50);
		 primary key (report_number);
	);

	create table owns
	(
		 driver_id   varchar(50),
		 license     varchar(50),
		 primary key(driver_id),
		 foreign key (driver_id) references person,
		 foreign key (license) references car
	);

	create table participated
	(
		 report_num    varchar(10),
		 license       varchar(50),
		 driver_id     varchar(50),
		 damage_amount numeric(10,0),
		 primary key (report_number,license),
		 foreign key (report_number) references accident,
		 foreign key (license) references car,
		 foreign key (driver_id) references owns
	);

3.14考慮圖3-18中的保險公司數據庫,其中加下划線的是主碼。對這個關系數據庫構造如下的SQL查詢。

a.找出和John Smith的車有關的交通事故數量。

	select count(report_number)
	  from participated
	 where license in (select license 
						 from person natural join owns
						where name = 'John Smith');

b.對事故報告編號為AR2197中的車牌是AABB2000的車輛損壞保險費用更新到3000美元。

	update participated
	   set damage_amount
	 where report_number = 'AR2197' and license = 'AABB2000';

3.15 考慮圖3-19中的銀行數據庫,其中加下划線的是主碼。為這個關系數據庫構造出如下的SQL查詢。

a.找出在Brooklyn的所有支行都有賬戶的所有客戶。

	with branchcount as
	(
		 select count(*)
		   from Branch
		   where branch_city = 'Brooklyn'
	)
	select custumer_name 
	  from customer c
	 where branchcount = (select count(distinct branch_name)
							from (customer natural join depositor natural join account natural join branch) as d
						   where d.customer_name = c.customer_name);

b.找出銀行的所有貸款額的總和。

	select sum(amount) 
	  from loan;

c.找出總資產至少比位於Brooklyn的所有支行的某一家支行要多的所欲支行的名字

	select branch_name
	  from branch
	 where assets > some(select assets
						   from branch
						  where branch_city = 'Brooklyn');

3.16 考慮圖3-20中的雇員數據庫,其中加下划線的是主碼。給出下面每個查詢對應的SQL查詢式。

a.找出所有為First Bank Corporation工作的雇員的名字。

	select employee_name
	  from works
	 where company_name = 'First Bank Corporation':

b.找出數據庫中所有居住城市和公司所在城市相同的雇員。

	select employee_name
	  from employee E join works using (employee_name) join company C using (company_name)
	 where E.city = C.city;

c.找出數據庫中所有居住城市和接到與其經理相同的雇員。

select P.employee_name
  from employee P,employee R,managers M
 where P.employee_name = M.employee_name
   and R.employee_name = M.manger_name
   and P.street = R.street
   and P.city = R.city;

d. 找出工資高於其所在公司雇員平均水平的所以雇員。

	with avg_salary
		 as (select company_name,avg(salary) as val
			   from works
			  group by company_name)
	select employee_name 
	  from works natural join avg_salary
	 where salary > val;

e.找出工資總和最小的公司。

	select  company_name
	  from  works
	 group  by company_name
	 having sum(salary) = (select Min(Sum(salary))
							 from works 
							group by company_name);

3.17 考慮圖3-20中的關系數據庫。給出下面每個查詢對應的SQL表達式。

a.為First Bank Corporation的所有雇員增長10%的工資。

	update works
	   set salary = salary * 1.10;
	 where company_name = 'First Bank Corporation';

b.為First Bank Corporation的所有經理增長10%的工資。

	update works
	   set salary = salary * 1.10;
	 where company_name = 'First Bank Corporation' and employee_name in (select manager_name from managers);l

c.刪除Small Bank Corporation的雇員在Works關系中的所有元組。

	delete from works
	 where company_name = 'First Bank Corporation';

3.21 考慮圖3-21中的圖書館數據庫。用SQL寫出如下查詢。

member(memb no, name, age)
book(isbn, title, authors, publisher)
borrowed(memb no, isbn, date)

a.打印借閱了任意由McGraw-Hill出版的書的會員的名字。

	select distinct name
	  from member natural join book natural join borrowed
	 where publisher = 'McGraw-Hill';

b.打印借閱了所有由McGraw-Hill出版的書的會員的名字。

	select name 
	  from member 
	 where memb_no in (select memb_no 
						 from borrowed 
						group by memb_no 
						having count(*) = (select count(*) 
						from book 
						where publisher='McGraw-Hill'));

c.對於每個出版商,打印借閱了多余五本由該出版社出版的書的會員名字。

	select name,publisher
	  from member natural join borrowed natural join book
	 group by name,publisher
	 having count(isbn) > 5;

d. 打印每一位會員借閱書籍數量的平均值。考慮這樣的情況:如果某會員沒有借閱任何書籍,那么該會員根本不會出現在borrowed關系中。

	select(select count(*) from borrowed)/ (select count(*)from member)

3.23考慮以下查詢,解釋為什么在from子句中還加上與section的連接不會改變查詢結果。

select course id, semester, year, section id, avg (credits earned)
from takes natural join student
where year = 2009
group by course id, semester, year, section id
having count (ID) >= 2;
解:takes 和 section 是通過一些共同的外鍵相連系,每一個takes的某一個元組不會因為增加額外的元祖。

3.24考慮以下查詢,不使用with結構,重寫此查詢。

with dept total (dept name, value) as
(select dept name, sum(salary)
from instructor
group by dept name),
dept total avg(value) as
(select avg(value)
from dept total)
select dept name
from dept total, dept total avg
where dept total.value >= dept total avg.value;
解:答案如下:
	select dept_name
	 from (select dept name, sum(salary)
			 from instructor
			group by dept name) P 
	 where P.val >= (select avg(sum(salary))
					   from instructor
					  group by dept_name);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM