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%'

 

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