数据库第一次做业(第三章)

数据库第一次做业

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);
相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息