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

數據庫第一次做業

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分,等等。學生在某門課程(課程段)上所獲取的等級分值被定義爲該課程段的學分乘以該生獲得的成績等級所對應的數字表示的得分。

/根據題意建立表/sql

/*建立表關係*/
    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);
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息