文章目录
- 查找最晚入职员工的所有信息
- 查找入职员工时间排名倒数第三的员工所有信息
- 查找各个部门当前(to_date='9999-01-01')领导当前薪水详情以及其对应部门编号dept_no
- 查找所有已经分配部门的员工的last_name和first_name,dept_no
- 查找所有员工的last_name和first_name以及对应部门编号dept_no,也包括展示没有分配具体部门的员工
- 查找所有员工入职时候的薪水情况,给出emp_no以及salary, 并按照emp_no进行逆序
- 查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数t:repeat:
- 找出所有员工当前(to_date='9999-01-01')具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示
- 获取所有部门当前manager的当前薪水情况,给出dept_no, emp_no以及salary,当前表示to_date='9999-01-01'
- 获取所有非manager的员工emp_no
- 获取所有员工当前的manager,如果当前的manager是自己的话结果不显示,当前表示to_date='9999-01-01'。结果第一列给出当前员工的emp_no,第二列给出其manager对应的manager_no。:repeat:
- 获取所有部门中当前员工薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary
- 从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。
- 从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。注意对于重复的title进行忽略。:repeat:
- 查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列
- 统计出当前各个title类型对应的员工当前(to_date='9999-01-01')薪水对应的平均工资。结果给出title以及平均工资avg。
- 获取当前(to_date='9999-01-01')薪水第二多的员工的emp_no以及其对应的薪水salary
- 查找当前薪水(to_date='9999-01-01')排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,不准使用order by
- 查找所有员工的last_name和first_name以及对应的dept_name,也包括暂时没有分配部门的员工
- 查找员工编号emp_no为10001其自入职以来的薪水salary涨幅值growth
- 查找所有员工自入职以来的薪水涨幅情况,给出员工编号emp_no以及其对应的薪水涨幅growth,并按照growth进行升序:repeat:
- 统计各个部门对应员工涨幅的次数总和,给出部门编码dept_no、部门名称dept_name以及次数sum
- 对所有员工的当前(to_date='9999-01-01')薪水按照salary进行按照1-N的排名,相同salary并列且按照emp_no升序排列
- 获取所有非manager员工当前的薪水情况,给出dept_no、emp_no以及salary ,当前表示to_date='9999-01-01'
- 获取员工其当前的薪水比其manager当前薪水还高的相关信息,当前表示to_date='9999-01-01',结果第一列给出员工的emp_no,
- 第二列给出其manager的manager_no,
- 第三列给出该员工当前的薪水emp_salary,
- 第四列给该员工对应的manager当前的薪水manager_salary
- 汇总各个部门当前员工的title类型的分配
- 给出每个员工每年薪水涨幅超过5000的信息
- 查找描述信息中包含robot的电影对应的分类名称以及电影数目,而且还需要该分类的电影数目>=5部
- 使用join查询方式找出没有分类的电影id以及名称
- 使用子查询的方式找出属于Action分类的所有电影对应的title,description
- 将employees表的所有员工的last_name和first_name拼接起来作为Name,中间以一个空格区分。
- 创建一个actor表,包含下列信息
- 对于表actor批量插入如下数据,如果数据已经存在,请忽略,不使用replace操作
- 创建一个actor_name表,将actor表中的所有first_name以及last_name导入该表。
- 创建索引
- 创建视图
- 使用强制索引
- 增加新列
- 创建触发器
- 删除某条记录
- 更新数据
- replace用法
- 表名重命名:smile:
- ==外键约束==
- 针对库中的所有表生成select count(*)对应的sql语句。
- 字符,字节等
- substr()函数
- group_concat()函数
- 查找排除当前最大、最小salary之后的员工平均工资avg_salary.
- 分页查询
- 获取所有员工的emp_no、部门编号dept_no以及对应的bonus类型btype和received ,没有分配具体的员工不显示
- 使用含有关键字exists查找未分配具体部门的员工的所有信息。
- 获取有奖金的员工相关信息。
- 按照salary的累计和running_total,其中running_total为前两个员工的salary累计和,其他以此类推。
- 对于employees表中,给出奇数行的first_name.
查找最晚入职员工的所有信息
select *
from employees
order by hire_date desc limit 1;
查找入职员工时间排名倒数第三的员工所有信息
select * from employees
order by hire_date desc limit 2,1;
查找各个部门当前(to_date=‘9999-01-01’)领导当前薪水详情以及其对应部门编号dept_no
select s.*,d.dept_no
from salaries as s inner join dept_manager as d
on s.to_date='9999-01-01'
and d.to_date='9999-01-01'
and s.emp_no=d.emp_no
查找所有已经分配部门的员工的last_name和first_name,dept_no
select e.last_name,e.first_name,d.dept_no
from employees as e inner join dept_emp as d
on e.emp_no=d.emp_no
查找所有员工的last_name和first_name以及对应部门编号dept_no,也包括展示没有分配具体部门的员工
select e.last_name,e.first_name,d.dept_no
from employees as e left join dept_emp as d
on e.emp_no=d.emp_no
查找所有员工入职时候的薪水情况,给出emp_no以及salary, 并按照emp_no进行逆序
select e.emp_no,s.salary
from employees as e inner join salaries as s
on e.emp_no=s.emp_no
and e.hire_date=s.from_date
order by e.emp_no desc
查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数t?
select emp_no,count(emp_no)as t
from salaries
group by emp_no
having t>15
找出所有员工当前(to_date=‘9999-01-01’)具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示
select distinct salary
from salaries
where to_date='9999-01-01'
order by salary desc
获取所有部门当前manager的当前薪水情况,给出dept_no, emp_no以及salary,当前表示to_date=‘9999-01-01’
select d.dept_no,d.emp_no,s.salary
from dept_manager as d,salaries as s
where d.emp_no=s.emp_no
and d.to_date='9999-01-01'
and s.to_date='9999-01-01'
获取所有非manager的员工emp_no
select emp_no
from employees
where emp_no not in (select emp_no from dept_manager)
获取所有员工当前的manager,如果当前的manager是自己的话结果不显示,当前表示to_date=‘9999-01-01’。结果第一列给出当前员工的emp_no,第二列给出其manager对应的manager_no。?
select dp.emp_no,dm.emp_no
from dept_emp as dp inner join dept_manager as dm
on dp.dept_no=dm.dept_no
and dp.emp_no<>dm.emp_no
and dm.to_date='9999-01-01'
and dp.to_date='9999-01-01'
获取所有部门中当前员工薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary
select d.dept_no,d.emp_no,max(s.salary)
from dept_emp as d inner join salaries as s
on d.emp_no=s.emp_no
and d.to_date='9999-01-01'
and s.to_date='9999-01-01'
group by d.dept_no
从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。
select title,count(title) as t
from titles
group by title
having t>=2
从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。注意对于重复的title进行忽略。?
select distinct title,count(distinct emp_no)as t
from titles
group by title
having t>=2
查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列
select *
from employees
where emp_no%2=1
and last_name<>'Mary'
order by hire_date desc;
统计出当前各个title类型对应的员工当前(to_date=‘9999-01-01’)薪水对应的平均工资。结果给出title以及平均工资avg。
select t.title,avg(s.salary) as avg
from titles as t,salaries as s
where s.to_date='9999-01-01'
and t.to_date='9999-01-01'
and s.emp_no=t.emp_no
group by t.title
获取当前(to_date=‘9999-01-01’)薪水第二多的员工的emp_no以及其对应的薪水salary
select emp_no,max(salary)
from salaries
where to_date='9999-01-01'
and salary not in (select max(salary) from salaries)
或者
select emp_no,salary
from salaries
where to_date='9999-01-01'
order by salary desc limit 1,1
查找当前薪水(to_date=‘9999-01-01’)排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,不准使用order by
select s.emp_no,max(s.salary),e.last_name,e.first_name
from salaries as s,employees as e
where s.emp_no=e.emp_no
and s.to_date='9999-01-01'
and s.salary not in (select max(salary) from salaries)
查找所有员工的last_name和first_name以及对应的dept_name,也包括暂时没有分配部门的员工
select e.last_name,e.first_name,d.dept_name
from employees as e left join dept_emp as dp
on e.emp_no=dp.emp_no
left join departments as d
on d.dept_no=dp.dept_no
查找员工编号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 limit 1)
as growth
查找所有员工自入职以来的薪水涨幅情况,给出员工编号emp_no以及其对应的薪水涨幅growth,并按照growth进行升序?
select a.emp_no,(b.salary-c.salary)as growth
from employees as a
inner join
salaries as b
on a.emp_no=b.emp_no
and b.to_date='9999-01-01'
inner join
salaries as c
on c.emp_no=b.emp_no
and a.hire_date=c.from_date
order by growth
统计各个部门对应员工涨幅的次数总和,给出部门编码dept_no、部门名称dept_name以及次数sum
答案
select dp.dept_no,d.dept_name,count(s.salary)as sum
from dept_emp as dp,departments as d,salaries as s
where d.dept_no=dp.dept_no
and dp.emp_no=s.emp_no
group by d.dept_no
自己写的(属实垃圾)?
select d.dept_no,d.dept_name,new.sum
from departments as d
inner join
(select dp.dept_no,count(s.salary) as sum
from dept_emp as dp,salaries as s
where dp.emp_no=s.emp_no
group by dp.dept_no)as new
on d.dept_no=new.dept_no
对所有员工的当前(to_date=‘9999-01-01’)薪水按照salary进行按照1-N的排名,相同salary并列且按照emp_no升序排列
自己写的,属实优秀??
select emp_no,salary,dense_rank() over (order by salary desc)
from salaries
where to_date='9999-01-01'
答案写的
select s1.emp_no,s1.salary,count(distinct s2.salary) rank
from salaries s1, salaries s2
where s1.salary <= s2.salary and s1.to_date = '9999-01-01' and s2.to_date = '9999-01-01'
group by s1.emp_no order by rank;
获取所有非manager员工当前的薪水情况,给出dept_no、emp_no以及salary ,当前表示to_date=‘9999-01-01’
select dp.dept_no,dp.emp_no,s.salary
from dept_emp as dp,salaries as s
where dp.emp_no not in (select emp_no from dept_manager where to_date='9999-01-01')
and dp.emp_no = s.emp_no
and dp.to_date='9999-01-01'
and s.to_date='9999-01-01'
获取员工其当前的薪水比其manager当前薪水还高的相关信息,当前表示to_date=‘9999-01-01’,结果第一列给出员工的emp_no,
第二列给出其manager的manager_no,
第三列给出该员工当前的薪水emp_salary,
第四列给该员工对应的manager当前的薪水manager_salary
select a.emp_no,b.emp_no as manager_no,a.salary as emp_salary,b.salary as manager_salary
from
(select dp.emp_no,dp.dept_no,s.salary
from dept_emp as dp,salaries as s
where dp.emp_no=s.emp_no
and s.to_date='9999-01-01'
and dp.emp_no not in (select emp_no from dept_manager))as a,
(select dm.emp_no,dm.dept_no,s.salary
from dept_manager as dm,salaries as s
where dm.emp_no=s.emp_no
and s.to_date='9999-01-01')as b
where a.salary>b.salary
and a.dept_no=b.dept_no
本题思想,制作两张表,一个员工表,一个经理表
汇总各个部门当前员工的title类型的分配
select dp.dept_no ,dm.dept_name,t.title,count(t.title)as count
from titles as t inner join dept_emp as dp
on t.emp_no=dp.emp_no
and t.to_date='9999-01-01'
and dp.to_date='9999-01-01'
inner join departments as dm
on dm.dept_no=dp.dept_no
group by dp.dept_no,t.title
自己写的
select d.dept_no,d.dept_name,t.title,count(t.emp_no)as count
from departments as d,dept_emp as dp,titles as t
where d.dept_no=dp.dept_no
and dp.emp_no=t.emp_no
and dp.to_date='9999-01-01'
and t.to_date='9999-01-01'
group by d.dept_no,t.title
给出每个员工每年薪水涨幅超过5000的信息
select s2.emp_no,s2.from_date,(s2.salary-s1.salary)as salary_growth
from salaries as s1,salaries as s2
where s1.emp_no=s2.emp_no
and salary_growth>5000
and (strftime('%Y',s2.to_date)-strftime('%Y',s1.to_date)=1
or strftime('%Y',s2.from_date)-strftime('%Y',s1.from_date)=1)
order by salary_growth desc
查找描述信息中包含robot的电影对应的分类名称以及电影数目,而且还需要该分类的电影数目>=5部
select c.name,count(fc.film_id)
from (select category_id,count(film_id)as category_num from film_category group by category_id having count(film_id)>=5) as cc,
film as f,
category as c,
film_category as fc
where f.description like'%robot%'
and f.film_id=fc.film_id
and c.category_id=fc.category_id
and cc.category_id=c.category_id
使用join查询方式找出没有分类的电影id以及名称
select f.film_id,f.title
from film as f left join film_category as fc
on f.film_id=fc.film_id
where fc.category_id is null
使用子查询的方式找出属于Action分类的所有电影对应的title,description
select f.title,f.description
from film as f,(select fc.film_id from film_category as fc,category as c
where c.category_id=fc.category_id
and c.name='Action')as new
where f.film_id=new.film_id
这个是自己写的
select title,description
from film
where film.film_id in
(select fc.film_id from film_category as fc,category as c
where c.category_id=fc.category_id
and c.name='Action')
以下这两个都是网上的
select title,description
from film
where film.film_id in
(select film_id
from film_category
where category_id in (
select category_id
from category
where name='Action'))
select title,description
from film
where film.film_id in
(select film_id
from film_category
where category_id in (
select category_id
from category
where name='Action'))
将employees表的所有员工的last_name和first_name拼接起来作为Name,中间以一个空格区分。
这是sqlite的方法
select last_name||" "|| first_name
from employees
这是mysql的方法
select concat(last_name,' ',first_name)
from employees
创建一个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'))
);
对于表actor批量插入如下数据,如果数据已经存在,请忽略,不使用replace操作
INSERT or ignore INTO ACTOR
(actor_id,first_name,last_name,last_update)
values(
3,'ED','CHASE','2006-02-15 12:34:33'
)
创建一个actor_name表,将actor表中的所有first_name以及last_name导入该表。
create table actor_name
(
first_name varchar(45) not null,
last_name varchar(45) not null
);
insert into actor_name
select first_name,last_name
from actor;
创建索引
创建唯一索引
create unique index 索引名 on 表名(某列名)
创建普通索引
create index 索引名 on 表名(某列名)
create unique index uniq_idx_firstname on actor(first_name);
create index idx_lastname on actor(last_name);
创建视图
我觉得视图就像是一个虚拟新表,后来执行查询时就可以在这个虚拟新表中进行。
create view 视图名 as
select ...
from...
...
create view actor_name_view as
select first_name as first_name_v,last_name as last_name_v
from actor;
使用强制索引
mysql
select|delete|update column1,column2,...
forced index index_name
where (condition);
sqlite
select|delete|update column1,column2,...
from table_name
indexed by index_name
where (condition);
增加新列
alter table table_name
add column column_name type ...,
add column column_name type ...;
alter table actor
add column create_date datetime not null default('0000 00:00:00')
创建触发器
create trigger audit_log after insert on employees
begin
insert into audit values(new.id,new.name);
end;
删除某条记录
delete from table_name
where (condition)
delete from titles_test
where id not in (select min(id) from titles_test group by emp_no);
更新数据
update table_name
set
更新要求1,
更新要求2,
...
where(condition)
update titles_test
set
to_date=NULL,
from_date='2001-01-01'
where to_date='9999-01-01';
replace用法
update table_name
set column_name=replace(column_name,str1,str2)
where(condition)
把表的column_name列的str1替换为str2
update titles_test
set emp_no=replace(emp_no,10001,10005)
where id =5;
表名重命名?
alter table table_name
rename [to|as] new_table_name;
或者(但是下面这种在牛客网上不通过,在mysql上可以通过)
rename table table_name to new_table_name;
修改表名,to或as都可以,也可省略to或as
alter table titles_test
rename titles_2017;
外键约束
将所有获取奖金的员工当前的薪水增加10%。
update salaries
set salary=salary*1.1
where emp_no in (select emp_no from emp_bonus)
and to_date='9999-01-01'
针对库中的所有表生成select count(*)对应的sql语句。
这题答案是用sqlite写的
select "select count(*) from "||name|| ';'as cnts
from sqlite_master where type='table';
1.在 SQLite 系统表 sqlite_master 中可以获得所有表的索引,其中字段 name 是所有表的名字,而且对于自己创建的表而言,字段 type 永远是 ‘table’,详情可参考:博客
2.在 SQLite 中用 “||” 符号连接字符串
mysql写法:
select concat("select count(*) from",' ',table_name,";")as cnts
from (select table_name from information_schema.tables) as new;
这里要注意必须给from后面的这个表加一个别名,不然会出现every derived table must has its own alias的错误。
将employees表中的所有员工的last_name和first_name通过(‘)连接起来。
myql写法:
select concat(last_name,"'",first_name)as name
from employees;
sqlite写法:
select last_name||"'"||first_name as name
from employees;
字符,字节等
1个汉字=1个字=1个字符
一个字母=一个字符=1个字节
1个字符=1个字节=8bit(ASCII码)
1个字符=2个字节=16bit(Unicode码下)
1个字符=3个字节(utf-8)
length()计算的是字节长度
char_length()计算的是字符长度
查找字符串’10,A,B‘中逗号’,'出现的次数cnt.
select lenth('10,A,B')-length(replace('10,A,B',',','')) as cnt;
substr()函数
substr(str,pos),从postion位置开始的往后的所有字符
substr(str from pos),同上
substr(str,pos,len),从position位置开始的往后的len个字符
select first_name
from employees
order by substr(first_name,-2);
或者:
select first_name
from employees
order by substr(first_name,-2,2);
group_concat()函数
官方文档
例子:
按班级进行汇总,把同一班级的用逗号隔开。group_concat()默认是用逗号隔开的
牛客网题目:按照dept_no汇总,属于同一个部门的emp_no按照逗号进行连接,结果给出dept_no以及连接出的结果employees.
select dept_no,group_concat(emp_no)as employees
from dept_emp
group by dept_no;
查找排除当前最大、最小salary之后的员工平均工资avg_salary.
select avg(salary) as avg_salary
from salaries
where salary not in (select max(salary) from salaries)
and salary not in (select min(salary) from salaries)
and to_date='9999-01-01';
分页查询
select column_1,column_2 from table_name limit 偏移量,查询条数;
分页查询employees,每5行一页,返回第2页的数据
select * from employees limit 5,5;
偏移量从0计数 ,每5行一页,那么第2页的数据是6-10行,所以limit5,5是从第6行起查询5条数据
获取所有员工的emp_no、部门编号dept_no以及对应的bonus类型btype和received ,没有分配具体的员工不显示
select e.emp_no,dp.dept_no,eb.btype,eb.recevied
from employees as e inner join dept_emp as dp
on e.emp_no=dp.emp_no
left join emp_bonus as eb
on dp.emp_no=eb.emp_no;
使用含有关键字exists查找未分配具体部门的员工的所有信息。
select * from employees
where not exists (select emp_no from dept_emp
where dept_emp.emp_no=employees.emp_no);
获取有奖金的员工相关信息。
给出emp_no、first_name、last_name、奖金类型btype、对应的当前薪水情况salary以及奖金金额bonus。 bonus类型btype为1其奖金为薪水salary的10%,btype为2其奖金为薪水的20%,其他类型均为薪水的30%。 当前薪水表示to_date=‘9999-01-01’。
考察case when用法。
case column_name
when column_name满足某条件 then
when···
else ···
end
答案
select eb.emp_no,e.first_name,e.last_name,eb.btype,s.salary,
(case eb.btype
when 1 then s.salary*0.1
when 2 then s.salary*0.2
else s.salary*0.3
end)as bonus
from emp_bonus as eb,employees as e,salaries as s
where eb.emp_no=e.emp_no
and eb.emp_no=s.emp_no
and s.to_date='9999-01-01';
我自己写的
select bb.emp_no,e.first_name,e.last_name,bb.btype,bb.salary,bb.bonus
from (select eb.emp_no,eb.btype,s.salary,
(case eb.btype
when 1 then s.salary*0.1
when 2 then s.salary*0.2
else s.salary*0.3
end
)as bonus
from emp_bonus as eb inner join salaries as s
on eb.emp_no = s.emp_no
and s.to_date='9999-01-01') as bb
inner join employees as e
on bb.emp_no=e.emp_no;
按照salary的累计和running_total,其中running_total为前两个员工的salary累计和,其他以此类推。
select a.emp_no,a.salary,sum(b.salary) as running_total
from salaries as a,salaries as b
where a.emp_no>=b.emp_no
and a.to_date='9999-01-01'
and b.to_date='9999-01-01'
group by a.emp_no;
对于employees表中,给出奇数行的first_name.
select first_name
from employees as a
where (select count(*) from employees as b
where b.first_name>=a.first_name)%2=1;
自己写的(牛客网上不通过,但是mysql上可以通过)
select first_name
from employees,(select @rownum:=0)as r
where (@rownum:=@rownum+1)%2=1;