SQL -2

1  查找員工編號emp_no爲10001其自入職以來的薪水salary漲幅值growth

 

select(

(select salary from salaries where emp_no=10001 order by to_date desc limit 1)-

(select salary from salaries where emp_no=10001 order by to_date asc limit 1)

)

as growth 

 

2  彙總各個部門當前員工的title類型的分配數目,結果給出部門編號dept_no、dept_name、其當前員工所有的title以及該類型title對應的數目count

 

select de.dept_no,d.dept_name,t.title,count (t.title) as count

 

from departments d inner join dept_emp de on d.dept_no = de.dept_no 

and de.to_date='9999-01-01'

 

inner join titles t on t. emp_no =de.emp_no

and t.to_date='9999-01-01'

 

group by de.dept_no,t.title

 

給出每個員工每年薪水漲幅超過5000的員工編號emp_no、薪水變更開始日期from_date以及薪水漲幅值salary_growth,並按照salary_growth逆序排列。

 

提示:在sqlite中獲取datetime時間對應的年份函數爲strftime(‘%Y’, to_date)

 

select s1.emp_no,s1.from_date,(s1.salary-s2.salary) as salary_growth 

from salaries s1,salaries s2

where (strftime('%Y',s1.to_date)-strftime('%Y',s2.to_date))=1

and salary_growth>5000

and s1.emp_no=s2.emp_no       ######重要

order by salary_growth desc

 

 使用含有關鍵字exists查找未分配具體部門的員工的所有信息。

 

select *

from employees e 

where not exists  (select emp_no from dept_emp d where e.emp_no = d.emp_no) 

 

5  對於employees表中,給出奇數行的first_name

 

select e1.first_name

from employees e1

where (select count(*) from employees e2 where e1.first_name<=e2.first_name) %2=1

 

6  針對庫中的所有表生成select count(*)對應的SQL語句

 

select "select count(*) from "||name||";" as cnts 

from sqlite_master where type='table'

 

7  將所有獲取獎金的員工當前的薪水增加10%。

 

update salaries set salary =salary*1.1 

where emp_no in (select s.emp_no from salaries s ,emp_bonus eb 

where eb.emp_no =s.emp_no

                  and s.to_date='9999-01-01')

 

8  在audit表上創建外鍵約束,其emp_no對應employees_test表的主鍵id。

 

實際mysql使用ALTER添加外鍵的語句表達式爲:ALTER TABLE tablename ADD FOREIGN KEY...REFERENCES...

 

drop table audit;

CREATE table audit(

    EMP_no int not null,

    create_date datetime not null,

foreign key(EMP_no) references employees_test(ID));

 

9  將titles_test表名修改爲titles_2017。

 

alter table titles_test rename to  titles_2017

 

10  將id=5以及emp_no=10001的行數據替換成id=5以及emp_no=10005,其他數據保持不變,使用replace實現。

 

本題運用 REPLACE 有兩種解法

方法一:全字段更新替換。由於 REPLACE 的新記錄中 id=5,與表中的主鍵 id=5 衝突,故會替換掉表中 id=5 的記錄,否則會插入一條新記錄(例如新插入的記錄 id = 10)。並且要將所有字段的值寫出,否則將置爲空。

 

replace into  titles_test  values ('5','10005','Senior Engineer','1986-06-26','9999-01-01')

 

方法二:運用REPLACE(X,Y,Z)函數。其中X是要處理的字符串,YX中將要被替換的字符串,Z是用來替換Y的字符串,最終返回替換後的字符串。以下語句用 UPDATEREPLACE 配合完成,用REPLACE函數替換後的新值複製給 id=5 emp_noREPLACE的參數爲整型時也可通過。

 

update titles_test set emp_no=replace(emp_no,10001,10005)where id =5

 

/** 另外可以利用OJ系統的漏洞,不用 REPLACE 實現  **/

 

UPDATE titles_test SET emp_no = 10005 WHERE id = 5

 

11  將所有to_date爲9999-01-01的全部更新爲NULL,且 from_date更新爲2001-01-01。

 

update titles_test set to_date=Null ,from_date='2001-01-01'

where to_date='9999-01-01'

 

12  刪除emp_no重複的記錄,只保留最小的id對應的記錄。

 

delete from titles_test where id

not in (select min(id) from titles_test group by emp_no)

 

13 1.創建觸發器使用語句:CREATE TRIGGER trigname;

2.指定觸發器觸發的事件在執行某操作之前還是之後,使用語句:

BEFORE/AFTER [INSERT/UPDATE/ADD] ON tablename

3.觸發器觸發的事件寫在BEGINEND之間;

4.觸發器中可以通過NEW獲得觸發事件之後2對應的tablename的相關列的值,OLD獲得觸發事件之前的2對應的tablename的相關列的值

 

create trigger audit_log after insert on employees_test

begin

insert into audit values (new.id,new.name);

end;

 

14  actor表中在last_update後面新增加一列名字爲create_date, 類型爲datetime, NOT NULL,默認值爲'0000 00:00:00'

 

ALTER TABLE ... ADD ... 語句可以向已存在的表插入新字段,並且能夠與創建表時一樣,在字段名和數據類型後加入NOT NULLDEFAULT等限定。

 

alter table  actor

add column 'create_date' datetime not null default '0000-00-00 00:00:00';

 

其中 ADD 後的 COLUMN 可省略,NOT NULL DEFAULT '0000-00-00 00:00:00' 可交換:

 

ALTER TABLE actor ADD create_date datetime DEFAULT '0000-00-00 00:00:00' NOT NULL ;

 

mysql中可以使用after.

15  SQLite中,使用 INDEXED BY 語句進行強制索引查詢

 

select * from salaries indexed by  idx_emp_no where emp_no=10005

 

MySQL中,使用 FORCE INDEX 語句進行強制索引查詢

 

SELECT * FROM salaries FORCE INDEX idx_emp_no WHERE emp_no = 10005

 

16   針對actor表創建視圖actor_name_view,只包含first_name以及last_name兩列,並對這兩列重新命名,first_name爲first_name_v,last_name修改爲last_name_v:

 

本題可用以下兩種方法求解,區別在於命名VIEW中字段名的方法差異。另外,本題OJ系統有Bug,由錯誤提示可以看到,VIEW中本應有字段first_name_v,而OJ系統誤設爲了fist_name_v

方法一:注意 CREATE VIEW ... AS ... AS 是創建視圖語法中的一部分,而後面的兩個 AS 只是爲字段創建別名

 

create view actor_name_view as 

select first_name as first_name_v,last_name as last_name_v

from actor

 

方法二:直接在視圖名的後面用小括號創建視圖中的字段名

 

create view actor_name_view (first_name_v,last_name_v) as 

select first_name ,last_name 

from actor

 

17  根據題意,本題要用兩條語句完成,先用 CREATE UNIQUE INDEX ... ON ... 對first_name創建唯一索引值,再用 CREATE INDEX ... ON ... 對last_name創建普通索引值

 

create unique index uniq_idx_firstname on actor(first_name);

create index idx_lastname on actor(last_name);

 

18   創建一個actor_name表,將actor表中的所有first_name以及last_name導入改表。 actor_name表結構如下:  

根據題意,本題要用兩條語句完成,先用 CREATE TABLE 語句創建actor_name表,包含first_namelast_name字段,然後用 INSERT INTO ... SELECT ... 語句向actor_name表插入另一張表中的數據  

 

create table actor_name(

first_name varchar(45) not null,

last_name varcher(45) not null

);

insert into actor_name select first_name,last_name from actor

 

19   對於表actor批量插入如下數據,如果數據已經存在,請忽略,不使用replace操作

 

SQLite 中,用 INSERT OR IGNORE 來插入記錄,或忽略插入與表內UNIQUE字段都相同的記錄

 

insert or ignore into actor 

values('3','ED','CHASE','2006-02-15 12:34:33')

 

INSERT OR REPLACE 來插入記錄,或更新替代與表內UNIQUE字段都相同的記錄

 

insert or replace into actor 

values('3','ED','CHASE','2006-02-15 12:34:33')

 

#######################################

因爲題目判定系統使用的是sqlite3,所以必須按sqlite3的寫法來做,

 

insert or ignore into actor

values(3,'ED','CHASE','2006-02-15 12:34:33');

 

如果是mysql,那麼把or去掉,像下面這樣:

 

insert IGNORE into actor

values(3,'ED','CHASE','2006-02-15 12:34:33');

 

兩種數據庫還是有區別的。

 

20  對於表actor批量插入如下數據

 

本題的批量插入數據要求在一條語句內完成,以下有兩種方法供參考:

法一:利用VALUES(value1, value2, ...), (value1, value2, ...), ...(value1, value2, ...),

 

insert into actor 

values(1,"PENELOPE","GUINESS",'2006-02-15 12:34:33'),

(2,"NICK","WAHLBERG",'2006-02-15 12:34:33');

 

方法二:利用 UNION SELECT 批量插入

 

insert into actor 

select 1,"PENELOPE","GUINESS",'2006-02-15 12:34:33' 

union select 2,"NICK","WAHLBERG",'2006-02-15 12:34:33'

21  創建一個actor表,包含如下列信息

 

create table actor(

actor_id smallint(5) not null primary key,

first_name varchar(45) not null,

last_name varchar(45) not null,

last_update timestamp not null default(datetime('now','localtime'))

)

 

//primary key(actor_id)

//最後一句不加逗號

 

22  將employees表中的所有員工的last_name和first_name通過(')連接起來。

 

在本題所用的SQLite數據庫中,只支持用連接符號"||"來連接字符串,不支持用函數連接

 

SELECT last_name || "'" || first_name FROM employees

 

空格鏈接的話 || “ ” ||

 

23  獲取select * from employees對應的執行計劃

 

SQLite數據庫中,可以用 "EXPLAIN" 關鍵字或 "EXPLAIN QUERY PLAN" 短語,用於描述表的細節。

 

explain select * from employees

 

24  使用子查詢的方式找出屬於Action分類的所有電影對應的title,description

 

//子查詢

select f.title,f.description 

from film f

where f.film_id in (select fc.film_id from film_category fc 

where fc.category_id in (select c.name="Action" from category c ))

 

//非子查詢

select f.title,f.description

from film f inner join film_category fc on f.film_id=fc.film_id

inner join category c on fc.category_id=c.category_id

where c.name='Action'

 

25  使用join查詢方式找出沒有分類的電影id以及名稱

 

解題思路是運用 LEFT JOIN 連接兩表,用 IS NULL 語句限定條件:

 

1、用 LEFT JOIN 連接 film film_category,限定條件爲 f.film_id = fc.film_id,即連接電影 id 和電影分類 id,如果電影沒有分類,則電影分類 id 顯示 null

 

2、再用 WHERE 來限定條件 fc.category_id IS NULL 選出沒分類的電影

 

/* 注意:最後一句若寫成 ON f.film_id = fc.film_id AND fc.category_id IS NULL,則意義變成左連接兩表 film_id 相同的記錄,且 film_category 原表中的 fc.category 的值爲 null。顯然,原表中的 fc.category 的值恆不爲 null,因此(f.film_id = fc.film_id AND fc.category_id IS NULL)恆爲 FALSE,左連接後則只會顯示 film 表的數據,而 film_category 表的數據全顯示爲 null */

 

select f.film_id,f.title  

from film f left join film_category fc 

on f.film_id=fc.film_id

where  fc.category_id is Null

 

26  查找描述信息中包括robot的電影對應的分類名稱以及電影數目,而且還需要該分類對應電影數量>=5部

 

1、找到對應電影數量>=5的所有分類,建立成虛表cc(select category_id, count(film_id) as category_num from  film_category  group by category_id having count(film_id)>=5) as cc

2、設定限制條件 f.description like '%robot%'

3、在表ccffcc中查找包括robot的電影對應的分類名稱和對應的電影數目

 

select  c.name,count(fc.film_id)  from   

(select category_id ,count(film_id )

 from film_category group by category_id

    having count(film_id)>=5

) as cc ,film f,film_category fc,category c

where f.film_id=fc.film_id

and c.category_id=fc.category_id

and c.category_id = cc.category_id

and f.description like '%robot%'

 

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