[數(shù)據(jù)庫之三] SQL

大學數(shù)據(jù)庫的設(shè)計模式:

【學院】department ( dept_name, building, budget )
【教師】instructor ( id, name, dept_name, salary )
【課程段】section ( course_id, sec_id, semester, year, building, room_number, time_slot_id )
【教師授課安排】teaches ( id, course_id, sec_id, semester, year )
【學生】student ( id, name, dept_name, tot_cred )
【學生課表】takes ( id, course_id, sec_id, semester, year, grade )
【課室】classroom ( building, room_number, capacity )
【上課時段】time_slot ( time_slot_id, day, start_time, end_time )
【課程】course ( course_id, title, dept_name, credits )
【先決條件(課程)】prereq ( course_id, prereq_id )

1、SQL 查詢的基本結(jié)構(gòu)

??SQL 查詢的基本結(jié)構(gòu)由三個子句構(gòu)成:select、from 和 where。查詢的輸入是在 from 子句中列出的關(guān)系,在這些關(guān)系上進行 where 和 select 子句中指定的運算,然后產(chǎn)生一個關(guān)系作為結(jié)果。

(1)單關(guān)系查詢

1、找出所有教師的名字

select name
from instructor;


2、找出所有老師所在系名

select dept_name
from instructor;

// 因為不同老師可能來自同個系,所以會得到重復的結(jié)果,為了去重,SQL 改為

select distinct dept_name
from instructor;        // 每個系最多只出現(xiàn)一次

// 如果想顯式指定使用關(guān)鍵字 all
select all dept_name
from instructor;


  • select 子句可帶含有 +、-、、/ 運算符的算術(shù)表達式*

3、顯示給每位教師增長 10% 的工資的結(jié)果。

select id, name, dept_name, salary * 1.1
from instructor;


  • where 子句允只選出在 from 子句的結(jié)果關(guān)系中滿足特定謂詞的元組。

4、找出所有在 Computer Science 系并且工資超過 70000 美元的教師的姓名。

select name
from instructor
where dept_name = 'Comp.Sci.' and salary > 70000;



(2)多關(guān)系查詢

??笛卡爾積、自然連接

5、找出所有教師的姓名,以及他們所在系的名字和系所在建筑的名稱。

// 笛卡爾積
select name, dept_name, building
from instructor, department
where instructor.dept_name = department.dept_name;

// 自然連接
select name, dept_name, building
from instructor nature join department;


6、對于大學中所有講授課程的老師,找出他們的名字以及所講述的所有課程標識。

// 笛卡爾積
select name, course_id
from instructor, teaches
where instructor.id = teaches.id;

// 自然連接
select name, course_id
from instructor nature join teaches;


7、列出教師的名字以及他們所講授課程的名稱。

select name, title
from (instructor nature join teaches) join course using(course_id);

select name, title
from instructor nature join teaches, course
where teaches.course_id = course.course_id;



2、附加的基本運算

(1)更名運算

??使用 as 關(guān)鍵字,常用于屬性更名、表簡稱等。

// 未使用更名前的 sql
select name, course_id
from instructor, teaches
where instructor.id = teaches.id;

// 為屬性更名,以更好地表達其含義
select name as instructor_name, course_id
from instructor, teaches
where instrcutor.id = teaches.id;

// 為表更名,方便書寫 sql
select T.name, S.course_id
from instructor as T, teaches as S
where T.id = S.id;



??有時需要把一個關(guān)系跟它自身進行笛卡爾積運算,重命名適合書寫這類 SQL

8、找出滿足下面條件的所有教師的姓名,他們的工資至少比 Biology 系某一個教師的工資要高。

select distinct T.name
from instructor as T, instructor as S
where S.dept_name = 'Biology' and T.salary > S.salary;


(2)字符串運算

??比較、串聯(lián)(使用 "||")、提取子串、計算字符串長度、大小寫轉(zhuǎn)換(upper(s)、lower(s))、去掉字符串后面的空格(trim(s))。

??模糊匹配(使用 like 關(guān)鍵字):

  • 百分號(%):匹配任意子串。
  • 下劃線(_):匹配任意一個字符。

9、找出所在建筑名稱中包含子串 ‘Waston’ 的所有系名。

select dept_name
from department
where dept_name like '%Waston%';


(3)排列元組的顯示次序

??使用 order by 關(guān)鍵字(asc 升序,desc 降序),讓查詢結(jié)果中元組按排列順序顯示。

10、按字母順序列出在 Physics 系的所有教師。

select name
from instructor
where dept_name = 'Physics'
order by name;


11、按工資降序,名字字母升序輸出所有教師的信息。

select *
from instructor
order by salary desc, name asc;


(4)where 子句謂詞

區(qū)間條件查詢,使用 between ... and ... 關(guān)鍵字

12、找出工資在 90000 美元和 100000 美元之間的教師的姓名。

select name
from instructor
where salary between 90000 and 100000;

select name 
from instructor
where salary >= 90000 and salary <= 100000;


13、查找 Biology 系講授了課程的所有教師的姓名和他們所講授的課程。

select name, course_id
from instructor, teaches
where dept_name = 'Biology' and instructor.id = teaches.id;

select name, course_id
from instructor, teaches
where (instructor.id, dept_name) = (teaches.id, 'Biology');

// 使用自然連接
select name, course_id
from instructor nature join teaches
where dept_name = 'Biology';



3、集合運算

并集:使用 union 關(guān)鍵字
交集:使用 intersect 關(guān)鍵字
差集:使用except 關(guān)鍵字

* 在2009年秋季學期開設(shè)的所有課程的集合。

    select course_id
    from section
    where semester = 'Fall' and year = 2009;

* 在2010年春季學期開設(shè)的所有課程的集合。

    select course_id
    from section
    where semester = 'Spring' and year = 2010;


(1)并運算

14、找出在2009年秋季開課,或者在2010年春季開課或兩學期都開課的所有課程。

// 使用集合運算的寫法
(select course_id
 from section
 where semester = 'Fall' and year = 2009)
 union
(select course_id
 from section
 where semester = 'Spring' and year = 2010);
 
Ps.union 會自動去重,如果想保留所有重復的 course_id,比如有的課程在兩個學期里開設(shè)了不止一次,就要使用 union all 關(guān)鍵字。


(2)交運算

15、找出在2009年秋季開課,并且也在2010年春季開課的所有課程。

(select course_id
 from section
 where semester = 'Fall' and year = 2009)
 intersect
(select course_id
 from section
 where semester = 'Spring' and year = 2010);
 
Ps.同樣保留重復要使用 intersect all。


(3)差運算

16、找出在2009年秋季開課,但不在2010年春季開課的所有課程。

(select course_id
 from section
 where semester = 'Fall' and year = 2009)
 except
(select course_id
 from section
 where semester = 'Spring' and year = 2010);
 
 Ps.同樣保留重復要使用 except all。


4、聚合函數(shù)

??常見通用的聚合函數(shù)有:

  • 平均值:avg。

  • 最小值:min。

  • 最大值:max。

  • 總和:sum。

  • 計數(shù):count。

    sum 和 avg 的輸入必須是數(shù)字集,聚合函數(shù)默認計算前不去重。

    一般使用 group by 關(guān)鍵字來指定分組,如果未顯式指定,則默認為關(guān)系中的所有元組。

(1)基本聚集

17、找出 Computer Science 系教師的平均工資。

select avg(salary)
from instructor
where dept_name = 'Comp.Sci.';


18、找出在 2010 年春季學期講授一門課程的教師總數(shù)。

select count(distinct id)
from teaches
where semester = 'Spring' and year = 2010;


(2)分組聚集

19、找出每個系的平均工資。

// 使用 group by 關(guān)鍵字來構(gòu)造分組
select dept_name, avg(salary) as avg_salary
from instructor
group by dept_name;

// 未指定則作用在所有元組上
找出所有教師的平均工資
select avg(salary)
from instructor;


20、找出每個系在 2010 年春季學期講授一門課程的教師人數(shù)

select dept_name, count(distinct id) as instr_count
from instructor nature join teaches
where semester = 'Spring' and year = 2010
group by dept_name;


(3)having 子句

??其實就相當于對每個分組分別進行 where 限定。

21、教師平均工資超過 42000 美元的系。

select dept_name, avg(salary) as avg_salary
from instructor
group by dept_name
having avg(salary) > 42000;


22、對于在 2009 年講授的每個課程段,如果該課程段有至少 2 名學生選課,選出選修該課程段的所有學生的總學分(tot_cred)的平均值。

select course_id, sec_id, semester, year, avg(tot_cred) as avg_tot_cred
from student nature join takes
where year = 2009
group by course_id, sec_id, semester, year
having count(id) >= 2;



5、嵌套子查詢

??子查詢是嵌套在另一個查詢中的 select-from-where 表達式。子查詢嵌套在 where 子句中,通常用于對集合的成員資格、集合的比較以及集合的基數(shù)進行檢查。

(1)集合成員資格

??使用 in/not in 關(guān)鍵字,測試元組是否是集合中的成員,集合是由 select 子句產(chǎn)生的一組值構(gòu)成的。

23、找出在 2009 年秋季和 2010 年春季學期同時開課的所有課程。(同15,使用嵌套子查詢的寫法)

select course_id
from section
where semester = 'Fall' and year = 2009
and course_id in (select course_id
                  from section
                  where semester = 'Spring' and year = 2010);


24、找出所有在 2009 年秋季學期開課,但不在 2010 年春季學期開課的課程(同16,使用嵌套子查詢寫法)

select course_id
from section
where semester = 'Fall' and year = 2009
and course_id not in (select course_id
                      from section
                      where semester = 'Spring' and year = 2010);


25、查詢找出既不叫 “Mozart” 也不叫 “Einstein” 的教師的姓名。

select name
from instructor
where name not in ('Mozart', 'Einstein');


(2)集合的比較

??嵌套子查詢能夠?qū)线M行比較,使用下面的關(guān)鍵字:

  • some 關(guān)鍵字:某些、某一個。
  • all 關(guān)鍵字:所有。

26、找出滿足下面條件的所有教師的姓名,他們的工資至少比 Biology 系某一個教師的工資要高。(同16,使用嵌套子查詢)

select name
from instructor
where salary > some(select salary
                    from instructor
                    where dept_name = 'Biology');


27、找出滿足下面條件的所有教師的姓名,他們的工資值比 Biology 系每個教師的工資都高。

select name
from instructor
where salary > all(select salary
                   from instructor
                   where dept_name = 'Biology');


28、找出平均工資最高的系。

select dept_name
from (select dept_name, avg(salary) as avg_salary
      from instructor
      group by dept_name)
where avg_salary = max(avg_salary);

select dept_name
from instructor
group by dept_name
having avg(salary) >= all(select avg(salary)
                          from instructor
                          group by dept_name);


(3)空關(guān)系測試

??使用 exists/not exists 關(guān)鍵字測試一個子查詢結(jié)果中是否存在元組。

29、找出在 2009 年秋季學期和 2010 年春季學期同時開課的所有課程。

select course_id
from section as S
where semester = 'Fall' and year = 2009 and
      exists (select *
              from section as T
              where semester = 'Spring' and year = 2010 and 
                    S.course_id = T.course_id);

相關(guān)子查詢:使用外層查詢的一個相關(guān)名稱(上述查詢中的 S)可以用在 where 子句的子查詢中,使用了來自外層查詢相關(guān)名稱的子查詢被稱作相關(guān)子查詢。


30、找出選修了 Biology 系開設(shè)的所有課程的學生。

select S.id, S.name
from student as S
where not exists ((select course_id
                   from course
                   where dept_name = 'Biology')
                  except
                  (select T.course_id
                   from takes as T
                   where S.id = T.id));


(4)重復元組存在性測試

??使用 unique 關(guān)鍵字測試作為參數(shù)的子查詢結(jié)果中是否有重復的元組。

31、找出所有在 2009 年最多開設(shè)一次的課程。

// 使用 unique 關(guān)鍵字
select T.course_id
from course as T
where unique (select R.course_id
              from section as R
              where T.course_id = R.course_id 
              and R.year = 2009);
              
// 使用聚合函數(shù)
select T.course_id
from course as T
where 1 >= (select count(R.course_id)
            from section as R
            where T.course_id = R.course_id
            and R.year = 2009);


32、找出所有在 2009 年最少開設(shè)兩次的課程。

// 使用 not unique 關(guān)鍵字,表示從集合中篩選出相同的 course_id 至少出現(xiàn)兩次的數(shù)據(jù)
select T.course_id
from course as T
where not unique (select R.course_id
                  from section as R
                  where T.course_id = R.course_id
                  and R.year = 2009);
                  select T.course_id
                  
// 使用聚合函數(shù)                 
from course as T
where 2 =< (select count(R.course_id)
            from section as R
            where T.course_id = R.course_id
            and R.year = 2009);


(5)from 子句的子查詢

??任何 select-from-where 表達式返回的結(jié)果都是關(guān)系,因而可以被插入到另一個 select-from-where 中任何關(guān)系可以出現(xiàn)的位置。

33、找出系平均工資超過 42000 美元的那些系中教師的平均工資。(同 21,使用子查詢寫法)

// 使用子查詢
select dept_name, avg_salary
from (select dept_name, avg(salary) as avg_salary
      from instructor
      group by dept_name)
where avg_salary > 42000;

// 使用 having 關(guān)鍵字
select dept_name, avg(salary) as avg_salary
from instructor
group by dept_name
having avg_salary > 42000;


34、找出在所有系中工資總額最大的系。

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


(6)with 子句

??使用 with 關(guān)鍵字,定義臨時關(guān)系。

35、找出具有最大預算值的系。

with max_budget(value) as
     (select max(budget)
      from instructor)
select budget
from department, max_budget
where department.budget = max_budget.budget;


36、查出所有工資總額大于所有系平均工資總額的系。

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;


(7)標量子查詢

??標量子查詢:該子查詢值返回包含單個屬性的單個元組。

37、找出所有的系及他們擁有的教師數(shù)。

// 使用自然連接和分組聚合的寫法
select dept_name, count(*) as ins_num
from instructor nature join department
group by dept_name;

// 使用標量子查詢的寫法
select dept_name, (select count(*)
                   from instructor
                   where department.dept_name = instructor.dept_name)
from department;



6、數(shù)據(jù)庫的修改

(1)刪除

38、從 instructor 關(guān)系中刪除與 Finance 系老師相關(guān)的所有元素。

delete from instructor where dept_name = 'Finance';


39、刪除所有工資在 13000 美元到 15000 美元之間的教師。

delete from instructor where salary between 13000 and 15000;


40、從 instructor 關(guān)系中刪除所有這樣的教師元組,他們在位于 Watson 大樓的系辦公。

delete from instructor, department
where instructor.dept_name = department.dept_name
and department.building = 'Watson';

delete from instructor
where dept_name in (select dept_name
                    from department
                    where building = 'Watson');


41、刪除工資低于大學平均工資的教師記錄。

delete from instructor
where salary < (select avg(salary) from instructor);


(2)插入

42、插入 Computer Science 系開設(shè)的名為 “Database Systems” 的課程 CS-437,它有 4 個學分。

// 元組屬性值的排列順序和關(guān)系模式中屬性排列的順序一致,可不顯示指定屬性
insert into course values('CS-437', 'Database System', 'Comp.Sci.', 4);

// 顯式指定屬性
insert into course(course_id, title, dept_name, credits)
        values ('CS-437', 'Database System', 'Comp.Sci.', 4);


  • 用 select 選出一個元組集合,并將其插入到關(guān)系中。

43、讓 Music 系每個修滿 144 學分的學生成為 Music 系的教師,其工資為 18000 美元。

insert into instructor
    select id, name, department, 18000
    from student
    where dept_name = 'Music' and tot_cred > 144;


(3)更新

44、所有教師的工資增長 5%。

update instructor
set salary = salary * 1.05;


45、只給那些工資低于 70000 美元的教師漲工資。

update instructor
set salary = salary * 1.05
where salary < 70000;


46、對工資低于平均數(shù)的教師漲 5% 的工資。

update instructor
set salary = salary * 1.05
where salary < (select avg(salary)
                from instructor);


47、給工資超過 100000 美元的教師漲 3% 的工資,其余教師漲 5%。

update instructor
set salary = salary * 1.03
where salary > 100000;

update instructor
set salary = salary * 1.05
where salary <= 100000;

// 使用 case 結(jié)構(gòu)
update instructor
set salary = case
        when salary <= 100000 then salary * 1.05
        else salary * 1.03
    end


48、如果一個學生在某門課程上的成績既不是 ‘F’ 也不是空,那么他成功學完了這門課程。

update student S
set tot_cred = (
    select sum(credits)
    from takes nature join course
    where S.id = takes.id 
    and takes.grade <> 'F'
    and takes.grade is not null);
    
// 更好地處理成績?yōu)?null 的情況    
update student S
set tot_cred = (
    select case
        when sum(credits) is not null then sum(credits)
        else 0
        end
    from takes nature join course
    where S.id = takes.id 
    and takes.grade <> 'F'
    and takes.grade is not null);



【習題】

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

a. 找出 Comp.Sci. 系開設(shè)的具有 3 個學分的課程名稱。
b. 找出名叫 Einstein 的教師所教的所有學生的標識,保證結(jié)果中沒有重復。
c. 找出教師的最高工資。
d. 找出工資最高的所有教師(可能不止一位教師具有相同的工資)。
e. 找出 2009 年秋季開設(shè)的每個課程段的選課人數(shù)。
f. 從 2009 年秋季開設(shè)的所有課程段中,找出最多的選課人數(shù)。
g. 找出在 2009 年秋季擁有最多選課人數(shù)的課程段。

a. select title
   from course
   where dept_name = 'Comp.Sci.' and credits = 3;
   
b. select distinct(takes.id)
   from (student join takes using(id))
        join
        (instructor join teaches using(id))
        using(course_id, sec_id, semester, year)
   where instructor.name = 'Einstein';
        
c. select max(salary) from instructor;

d. select name
   from instructor
   where salary = (select max(salary) from instructor);
   
e. select course_id, sec_id, count(id)
   from section nature join takes
   where semester = 'Autumn' and year = 2009
   group by course_id, sec_id;
   
f. select max(elect_num)
   from (select count(id) as elect_num
         from section nature join takes
         where semester = 'Autumn' and year = 2009
         group by course_id, sec_id);
         
g. with sec_enrollment as
  (select course_id, sec_id, count(id) as enrollment
   from section nature join takes
   where semester = 'Autumn' and year = 2009
   group by course_id, sec_id);
   
   select course_id, sec_id
   from sec_enrollment
   where enrollment = (select max(enrollment) from sec_enrollment);


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

??給定上述關(guān)系和我們的大學模式,用 SQL 寫出下面的每個查詢。為簡單起見,可以假設(shè)沒有任何 takes 元組在 grade 上取 null 值。

a. 根據(jù) ID 為 12345 的學生所選修的所有課程,找出該生所獲得的等級分值的總和。
b. 找出上述學生等級分值的平均值(GPA),即用等級分值的總和除以相關(guān)課程學分的總和。
c. 找出每個學生的 ID 和等級分值的平均值。

a. select sum(credits * points)
   from takes nature join course, grade_points
   where id = 12345 and takes.grade = grade_points.grade_e;

b. select sum(credits * points)/sum(credits) as GPA
   from takes nature join course, grade_points
   where id = 12345 and takes.grade = grade_points.grade_e;
   
c. select id, sum(credits * points)/sum(credits) as GPA
   from takes nature join course, grade_points
   where takes.grade = grade_points.grade_e
   group by id;


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

a. 給 Comp.Sci. 系的每位老師漲 10% 的工資。
b. 刪除所有未開設(shè)過(即沒有出現(xiàn)在 section 關(guān)系中)的課程。
c. 把每個在 tot_cred 屬性上取值超過 100 的學生作為同系的教師插入,工資為 10000 美元。

a. update instructor 
   set salary = salary * 1.1 
   where dept_name = 'Comp.Sci.';
   
b. delete from course 
   where course_id not in 
            (select distinct(course_id) from section);
            
c. insert into instructor
        select id, name, department, 10000
        from student
        where tot_cred > 100;


3.4 考慮圖 3-18 中保險公司數(shù)據(jù)庫,其中加下劃線的是主碼。為這個關(guān)系數(shù)據(jù)庫構(gòu)造如下 SQL 查詢:

a. 找出 2009 年其車輛出過交通事故的人員總數(shù)。
b. 向數(shù)據(jù)庫中增加一個新的事故,對每個必需的屬性可以設(shè)定任意值。
c. 刪除 “John Smith” 擁有的馬自達車(Mazda)

保險公司數(shù)據(jù)庫(PS.加粗為主鍵):

person ( driver_id, name, address )
car ( license, model, year )
accident ( report_number, date, location )
owns( driver_id, license )
participated( report_number, license, driver_id, damage_amount )

a. select count(distinct driver_id)
   from accident nature join participated
   where date between '2009-01-01' and '2009-12-31';
   
b. 

c. delete from car
   where model = 'Mazda' and license in (select license 
                                         from person nature join owns
                                         where person.name = 'John Smith');


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

a. 基于 marks 關(guān)系顯式每個學生的等級。
b. 找出各等級的學生數(shù)。

a. select ID, 
        case 
             when score < 40 then 'F'
             when score < 60 then 'C'
             when score < 80 then 'B'
             else 'A'
        end
   from marks;
 
b. with grades as 
   (select ID, 
        case 
             when score < 40 then 'F'
             when score < 60 then 'C'
             when score < 80 then 'B'
             else 'A'
        end as grade
    from marks);
    select grade, count(ID)
    from grades
    group by grade;


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

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


3.7 考慮下面的銀行數(shù)據(jù)庫,其中加下劃線的是主碼。為這個關(guān)系數(shù)據(jù)庫構(gòu)造出如下 SQL 查詢:

a. 找出銀行中所有有賬戶但無貸款的客戶。
b. 找出與 “Smith” 居住在同一個城市、同一個街道的所有客戶的名字。
c. 找出所有支行的名稱,在這些支行中都有居住在 “Harrison” 的客戶所開設(shè)的賬戶。

銀行數(shù)據(jù)庫:

branch ( branch_name, branch_city, assets )
customer ( customer_name, customer_street, customer_city )
loan ( loan_number, branch_name, amount )
borrower ( customer_name, load_number )
account ( account_number, branch_name, balance )
depositor ( customer_name, account_number )

a. (select customer_name from depositor)
   except
   (select customer_name from borrower);
   
b. select A.customer_name
   from customer as A, customer as B
   where B.customer_name = 'Smith' 
   and A.customer_city = B.customer_city
   and A.customer_street = B.customer_street;
   
   select F.customer_name
   from customer F join customer F using(customer_city, customer_street)
   and S.customer_name = 'Smith';
   
c. select distinct branch_name
   from account nature join depositor nature join customer
   where customer.customer_city = 'Harrison';


3.8 考慮下面的雇員數(shù)據(jù)庫,其中加下劃線的是主碼。為下面每個查詢寫出 SQL 表達式:

a. 找出所有為 "First Bank Corporation" 工作的雇員名字及其居住城市。
b. 找出所有為 "First Bank Corporation" 工作且薪金超過 10000 美元的雇員名字、居住街道和城市。
c. 找出數(shù)據(jù)庫中所有不為 "First Bank Corporation" 工作的雇員。
d. 找出數(shù)據(jù)庫中工資高于 "Small Bank Corporation" 的每個雇員的所有雇員。
e. 假設(shè)一個公司可以在好幾個城市有分部。找出位于 "Small Bank Corporation" 所有所在城市的所有公司。(有點拗口,就是找到在這家公司開設(shè)了分部的所有城市都有開設(shè)分部的公司)
f. 找出雇員最多的公司。
g. 找出平均工資高于 "First Bank Corporation" 平均工資的那些公司。
h. 修改數(shù)據(jù)庫使 "Jones" 現(xiàn)在居住在 "Newtown" 市。
i. 為 "First Bank Corporation" 所有工資不超過 100 000 美元的經(jīng)理增長 10% 的工資,對工資超過 100 000 美元的只增長 3%。

雇員數(shù)據(jù)庫:

employee ( employee_name, street, city )
works ( employee_name, company_name, salary )
company ( company_name, city )
managers ( employee_name, manager_name )

a. select employee_name, city
   from employee nature join works
   where works.company_name = 'First Bank Corporation';
   
b. select employee_name, street, city
   from employee nature join works
   where works.company_name = 'First Bank Corporation' 
   and works.salary > 10000;
   
c. select employee_name
   from works
   where company_name != 'First Bank Corporation';
   
d. select employee_name
   from works > all(select salary 
                    from works
                    where company_name = 'Small Bank Corporation');
                    
e. select S.company_name
   from company S
   where not exists ((select city 
                      from company
                      where company_name = 'Small Bank Corporation')
                      except
                     (select city
                      from company T
                      where S.company_name = T.company_name)
                     );

f. with employee_counts as (select company_name, count(distinct employee_name) as employee_count
                         from works
                         group by company_name);
   select company_name
   from employee_counts
   where employee_count = max(employee_count);

   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);

g. with comp_avg_salary as 
  (select company_name, avg(salary) as avg_salary
   from works
   group b company_name);
   
   select S.company_name
   from comp_avg_salary S, comp_avg_salary T
   where T.company_name = 'First Bank Corporation'
   and S.avg_salary > T.avg_salary;
   
   select company_name
   from works
   group by company_name
   having avg(salary) > (select avg(salary)
                         from works
                         where company_name = 'First Bank Corporation');
                         
h. update employee set city = 'Newtown' where employee_name = 'Jones';

i. update employee
   set salary = salary *
   (case
        when salary < 100000 then 1.1
        else 1.03
   end)
   where employee_name in (select employee_name
                           from managers nature join works
                           and works.company_name = 'First Bank Corporation');
                           
   update employee
   set salary = salary *
   (case
        when salary < 100000 then 1.1
        else 1.03
   end)
   where employee_name in (select employee_name
                           from managers);                           
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容