SQL题
1、取出sql表中第31到40的记录(以自动增长ID为主键)
sql server方案:
select top 10 * from t where id not in (select top 30 id from t order by id ) orde by id
mysql方案:
select * from t order by id limit 30,10
oracle方案:
select * from (select rownum r,* from t where r<=40) where r>30
2、用一条SQL语句 查询出每门课都大于80分的学生姓名
name kecheng fenshu
张三 语文 81
张三 数学 75
李四 语文 76
李四 数学 90
王五 语文 81
王五 数学 100
王五 英语 90
准备数据的sql代码:
create table score(id int primary key auto_increment,name varchar(20),subject varchar(20),score int);
insert into score values
(null,'张三','语文',81),
(null,'张三','数学',75),
(null,'李四','语文',76),
(null,'李四','数学',90),
(null,'王五','语文',81),
(null,'王五','数学',100),
(null,'王五 ','英语',90);
思路:转化为查出有<80分的学生姓名,然后排除这些学生剩下的就都是>80的了
select distinct name from score where name not in (select distinct name from score where score<=80)
3、所有部门之间的比赛组合
一个叫department的表,里面只有一个字段name,一共有4条纪录,分别是a,b,c,d,对应四个球对,现在四个球对进行比赛,用一条sql语句显示所有可能的比赛组合.
select a.name, b.name from team a, team b where a.name < b.name
4、请用SQL语句实现:从TestDB数据表中查询出所有月份的发生额都比101科目相应月份的发生额高的科目。请注意:TestDB中有很多科目,都有1-12月份的发生额。AccID:科目代码,Occmonth:发生额月份,DebitOccur:发生额。
准备数据的sql代码:
create table TestDB(id int primary key auto_increment,AccID varchar(20), Occmonth date, DebitOccur bigint);
insert into TestDB values
(null,'101','1988-1-1',100),
(null,'101','1988-2-1',110),
(null,'101','1988-3-1',120),
(null,'101','1988-4-1',100),
(null,'101','1988-5-1',100),
(null,'101','1988-6-1',100),
(null,'101','1988-7-1',100),
(null,'101','1988-8-1',100);
-- 复制上面的数据,故意把第一个月份的发生额数字改小一点
insert into TestDB values
(null,'102','1988-1-1',90),
(null,'102','1988-2-1',110),
(null,'102','1988-3-1',120),
(null,'102','1988-4-1',100),
(null,'102','1988-5-1',100),
(null,'102','1988-6-1',100),
(null,'102','1988-7-1',100),
(null,'102','1988-8-1',100);
-- 复制最上面的数据,故意把所有发生额数字改大一点
insert into TestDB values
(null,'103','1988-1-1',150),
(null,'103','1988-2-1',160),
(null,'103','1988-3-1',180),
(null,'103','1988-4-1',120),
(null,'103','1988-5-1',120),
(null,'103','1988-6-1',120),
(null,'103','1988-7-1',120),
(null,'103','1988-8-1',120);
-- 复制最上面的数据,故意把所有发生额数字改大一点
insert into TestDB values
(null,'104','1988-1-1',130),
(null,'104','1988-2-1',130),
(null,'104','1988-3-1',140),
(null,'104','1988-4-1',150),
(null,'104','1988-5-1',160),
(null,'104','1988-6-1',170),
(null,'104','1988-7-1',180),
(null,'104','1988-8-1',140);
-- 复制最上面的数据,故意把第二个月份的发生额数字改小一点
insert into TestDB values
(null,'105','1988-1-1',100),
(null,'105','1988-2-1',80),
(null,'105','1988-3-1',120),
(null,'105','1988-4-1',100),
(null,'105','1988-5-1',100),
(null,'105','1988-6-1',100),
(null,'105','1988-7-1',100),
(null,'105','1988-8-1',100);
此题的思路其实就是把科目为101的单独看成一个关联表,比较主表和关联表on中条件对应上的对应科目数据
-- 答案1
select distinct AccID from TestDB
where AccID not in
(select TestDB.AccID from TestDB,
(select * from TestDB where AccID='101') as db101
where TestDB.Occmonth=db101.Occmonth and TestDB.DebitOccur<=db101.DebitOccur
);
-- 答案2
select distinct AccID from TestDB
where AccID not in (
select distinct t1.AccID from TestDB t1 LEFT JOIN
(select * from TestDB where AccID='101') t2 on t1.Occmonth=t2.Occmonth
where t1.DebitOccur<=t2.DebitOccur )
5、统计每年每月的信息
year month amount
1991 1 1.1
1991 2 1.2
1991 3 1.3
1991 4 1.4
1992 1 2.1
1992 2 2.2
1992 3 2.3
1992 4 2.4
查成这样一个结果
year m1 m2 m3 m4
1991 1.1 1.2 1.3 1.4
1992 2.1 2.2 2.3 2.4
准备sql语句:
drop table if exists sales;
create table sales(id int auto_increment primary key,year varchar(10), month varchar(10), amount float(2,1));
insert into sales values
(null,'1991','1',1.1),
(null,'1991','2',1.2),
(null,'1991','3',1.3),
(null,'1991','4',1.4),
(null,'1992','1',2.1),
(null,'1992','2',2.2),
(null,'1992','3',2.3),
(null,'1992','4',2.4);
说明,这个其实也就是竖表转横表
-- 答案1
select YEAR,
min(case month when '1' then amount END ) m1,
min(case month when '2' then amount END ) m2,
min(case month when '3' then amount END ) m3,
min(case month when '4' then amount END ) m4
from sales GROUP BY YEAR -- 答案2
select s.year ,
(select t.amount from sales t where t.month='1' and t.year= s.year) 'm1',
(select t.amount from sales t where t.month='2' and t.year= s.year) 'm2',
(select t.amount from sales t where t.month='3' and t.year= s.year) 'm3',
(select t.amount from sales t where t.month='4' and t.year= s.year) 'm4'
from sales s group by s.year;
6、显示文章标题,发帖人、最后回复时间
表:id,title,postuser,postdate,parentid
准备sql语句:
drop table if exists articles;
create table articles(id int auto_increment primary key,title varchar(50), postuser varchar(10), postdate datetime,parentid int references articles(id));
insert into articles values
(null,'第一条','张三','1998-10-10 12:32:32',null),
(null,'第二条','张三','1998-10-10 12:34:32',null),
(null,'第一条回复1','李四','1998-10-10 12:35:32',1),
(null,'第二条回复1','李四','1998-10-10 12:36:32',2),
(null,'第一条回复2','王五','1998-10-10 12:37:32',1),
(null,'第一条回复3','李四','1998-10-10 12:38:32',1),
(null,'第二条回复2','李四','1998-10-10 12:39:32',2),
(null,'第一条回复4','王五','1998-10-10 12:39:40',1);
-- 第一种写法 非标准SQL,仅适合于MySql 因为mysql的分组查询列可以不在group by 字段中,
-- 而且聚合函数也不需要group by就可以单独使用
select a.title,a.postuser,
(select max(postdate) from articles where parentid=a.id) reply
from articles a where a.parentid is null; --第二种写法:标准SQL写法
select a2.title,a2.postuser,
(select max(a.postdate) from articles a
where a.parentid=a2.id GROUP BY a.parentid ) replytime
from articles a2 where a2.parentid is null
7、删除除了id号不同,其他都相同的学生冗余信息
create table student2(id int auto_increment primary key,code varchar(20),name varchar(20));
insert into student2 values(null,'2005001','张三'),(null,'2005002','李四'),(null,'2005001','张三');
如下语句,mysql报告错误,可能删除依赖后面统计语句,而删除又导致统计语句结果不一致。
delete from student2 where id not in(select min(id) from student2 group by name);
//于是,我想先把分组的结果做成虚表,然后从虚表中选出结果,最后再将结果作为删除的条件数据。先套一层,让子查询结果先出来再做删除,可能mysql内部没有处理这种一起关联时的先后顺序,所以只能多套一层了,这个在Oracle的rownum中也有类似现象,这点做的好的有MSSQL
delete from student2 where id not in(select mid from (select min(id) mid
from student2 group by name) as t);
8、航空网的几个航班查询题
表结构如下:
flight{flightID,StartCityID ,endCityID,StartTime}
city{cityID, CityName)
实验环境:
create table city(cityID int auto_increment primary key,cityName varchar(20));
create table flight (flightID int auto_increment primary key,
StartCityID int references city(cityID),
endCityID int references city(cityID),
StartTime time);
sql数据:
insert into city values(null,'北京'),(null,'上海'),(null,'广州');
insert into flight values
(null,1,2,'9:37:23'),(null,1,3,'9:37:23'),(null,1,2,'10:37:23'),(null,2,3,'10:37:23');
1)、查询起飞城市是北京的所有航班,按到达城市的名字排序
-- 方法1 左连接查询
select f.*,c.* from flight f
left join city c on f.startcityid=c.cityid
left join city c2 on f.endcityid=c2.cityid
where c.cityname='北京' ORDER BY c2.cityname asc
-- 方法2 嵌套子查询加笛卡尔积过滤
select * from flight f,city c
where f.endcityid = c.cityid and startcityid =
(select c1.cityid from city c1 where c1.cityname = "北京")
order by c.cityname asc;
2)、查询北京到上海的所有航班纪录(起飞城市,到达城市,起飞时间,航班号)
select f.flightid,f.starttime,c.cityname,c2.cityname from flight f
left join city c on f.startcityid=c.cityid
left join city c2 on f.endcityid=c2.cityid
where c.cityname='北京' and c2.cityname='上海'
9、一个用户具有多个角色,请查询出改表中具有该用户的所有角色的其他用户;
CREATE TABLE `emp` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`number` int(11) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`role` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `emp` VALUES (1,1001,'a','read');
INSERT INTO `emp` VALUES (2,1001,'a','write');
INSERT INTO `emp` VALUES (3,1001,'a','copy');
INSERT INTO `emp` VALUES (4,1002,'b','read');
INSERT INTO `emp` VALUES (5,1002,'b','write');
INSERT INTO `emp` VALUES (7,1003,'c','listen');
INSERT INTO `emp` VALUES (8,1003,'c','read');
INSERT INTO `emp` VALUES (9,1004,'d','read');
INSERT INTO `emp` VALUES (10,1004,'d','write');
INSERT INTO `emp` VALUES (11,1005,'e','read');
INSERT INTO `emp` VALUES (12,1005,'e','write');
-- 查出具有1002所有角色的用户
select e1.number from emp e1 ,(select * from emp where number=1002) e2
where e1.role =e2.role and e1.number!=e2.number
group by e1.number
having count(e1.number)
=(select count(e3.number)
from emp e3 where e3.number=1002
group by e3.number)
10、基于EMPLOYEES表写出查询:查出个人工资高于其所在部门平均工资的员工,列出这些员工的全部个人信息及该员工工资高出部门平均工资百分比。
Table EMPLOYEES Structure:
EMPLOYEE_ID NUMBER Primary Key,
FIRST_NAME VARCHAR2(25),
LAST_NAME VARCHAR2(25),
Salary number(8,2),
HiredDate DATE,
Departmentid number(2)
Table Departments Structure:
Departmentid number(2) Primary Key,
DepartmentName VARCHAR2(25).
select employee1.*,(employee1.salary-t.avgSalary)*100/employee1.salary
from employee1,
(select deptid,avg(salary) avgSalary from employee1 group by deptid) as t
where employee1.deptid = t.deptid and employee1.salary>t.avgSalary;
11、有一个Order表,表结构如下:
1 A 张三 1000
2 A 李四 500
3 C 赵五 2000
4 A 张三 1500
5 C 赵五 1500
6 A 张三 500
7 B 王六 800
8 B 钱七 1000
9 B 王六 1500
sql准备如下:
CREATE TABLE `order` (
`orderID` int(11) DEFAULT NULL,
`region` varchar(255) DEFAULT NULL,
`sales` varchar(255) DEFAULT NULL,
`total` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `order` VALUES ('1', 'A', '张三', '1000');
INSERT INTO `order` VALUES ('2', 'A', '李四', '500');
INSERT INTO `order` VALUES ('3', 'C', '赵五', '2000');
INSERT INTO `order` VALUES ('4', 'A', '张三', '1500');
INSERT INTO `order` VALUES ('5', 'C', '赵五', '1500');
INSERT INTO `order` VALUES ('6', 'A', '张三', '500');
INSERT INTO `order` VALUES ('7', 'B', '王六', '800');
INSERT INTO `order` VALUES ('8', 'B', '钱七', '1000');
INSERT INTO `order` VALUES ('9', 'B', '王六', '1500');
-- 1、统计出每个地区的合同金额合计并按此倒序排列显示
select region,sum(total) from `order` GROUP BY region
-- 2、统计出每个地区销售人员数量
-- select region '地区', count(sales) '销售人员数量' from `order` GROUP BY region,sales
-- 上为错误写法,直接分组统计会导致同一地区同一销售的的重复记录,结果不准确,得先过滤掉重复数据再统计
select t.region '地区' ,count(t.region) '销售人员数量' from (select distinct region,sales from `order`) t GROUP BY t.region
-- 3、统计出每个地区合同金额最少的销售人员
select t1.* from
(select o3.region o3_region,o3.sales o3_sales,sum(o3.total) o3_sumTotal from `order` o3 GROUP BY o3.region,o3.sales) t1
LEFT JOIN
(select o2.o1_region o2_region,min(o2.o1_sumTotal) o2_minTotal
from (
select o1.region o1_region,o1.sales o1_sales,sum(o1.total) o1_sumTotal from `order` o1 GROUP BY o1.region,o1.sales
) o2 group BY o2.o1_region
-- 单独通过t2这一步可以统计出各个地区的合同金额最少的销售的金额值,但是无法得出销售姓名,
-- 因为不能按照销售分组,采用min(sales)数据结果会出现偏差,所以还得外层再套一下,这步不能少
) t2 on t1.o3_region = t2.o2_region
where t1.o3_sumTotal=t2.o2_minTotal
-- 4、统计出所有超过本地区合同金额平均值的合同及金额
select o2.* from `order` o2,
(select o1.region o1_region,avg(o1.total) o1_avgTotal from `order` o1 GROUP BY o1.region ) t1
where o2.region=t1.o1_region and o2.total>t1.o1_avgTotal;
12、Oracle的rowid和rownum的区别,写出查询3-10条的分页记录
答:rowid和rownum都是Oracle的伪列,区别是rowid是属于具体表记录上的地址信息,是用16进制表示的,可以通过此地址信息快速定位到具体记录行,但是rownum并不是属于表本身,而是每次查询结果集返回之前Oracle自动添加的一个数据排列int索引,类似于号码牌,rownum根据结果集条数不同数值不同,其每次都是从1开始的,所以不能直接进行大于1的区间过滤,但是<的过滤没问题,直接查=1的结果也可以出来,但是查=其他数值的话查不出来,所以只能把结果再转一下成中间表再过滤
分页:
select * from (select rownum r, e.* from emp e where rownum <=10) t
where t.r>3
rownum可以起别名,但是具体使用时如where条件中不能用别名,只能用rownum,且如果select * 必须指定表别名.* 不能直接* ,rowid也一样,不能直接*,
select rowid r,e.* from emp e; -- ok
select rowid,* from emp -- erorr
SQL题的更多相关文章
- SQL题(子文章)(持续更新)
-----> 总文章 入口 文章目录 [-----> 总文章 入口](https://blog.csdn.net/qq_37214567/article/details/90174445) ...
- Sql题面试题
哪位大神会此题,请给出答案,十分感谢! 哪位大神会此题,请给出答案,十分感谢!
- 几道比较难的SQL题
上条记录和下一条记录 在展示博客文章时,在文章底部需要展示上一篇文章和下一篇文章,文章的排序当然是按照时间排序的. 选定下一条时可以用limit 1来实现,选取上一条时可以倒序limit 1实现 (S ...
- 一道SQL题
原题:大池子博客 给定一个access_time表,它记录了用户每个月访问网站的次数,包括三个域:用户.时间.次数.注意表中可能包含用户在1月份的多条记录. 要求查询用户.月份.月累计.总共累计四项的 ...
- 面试题中经常遇到的SQL题:删除重复数据,保留其中一条
如题,解决思路如下: 1.首先我们需要找出拥有重复数据的记录 ---以name字段分组 select Name,COUNT(Name) as [count] from Permission group ...
- 面试三轮我倒在了一道sql题上——sql性能优化
一.前言 最近小农在找工作,因为今年疫情的特殊原因,导致工作不是特别好找,所以一旦有面试电话,如果可以,都会去试一试,刚好接到一个面试邀请,感觉公司还不错,于是就确定了面试时间,准备了一下就去面试了. ...
- 关于分组查询的一道sql题
背景:想做一道sql的测试题,题目为: 按照角色分组算出每个角色按有办公室和没办公室的统计人数(列出角色,数量,有无办公室,注意一个角色如果部分有办公室,部分没有需分开统计) 如下,构造测试环境与对应 ...
- 一道SQL题考你数据库的使用能力
题目:数据库中存在例如以下数据,求用户终于剩余金额. 用户 类型 金额 A 存入 100 A 存入 200 A 取出 100 A 取出 200 A 存入 300 A 取出 300 本人Oracle接触 ...
- Oracle数据库 常见的SQL题,复习
01.查询员工表所有数据,并说明使用*的缺点 select * from emp 02.查询职位(JOB)为'PRESIDENT'的员工的工资 select sal from emp where jo ...
随机推荐
- 小知识,大智慧(restframework 拾忆)
一.直接对query_set序列化,在页面展示的效果是Unicode 编码格式 ,可在json 序列化时候加入一个参数 course_query = DegreeCourse.objects.all( ...
- 【Android 多语言切换简单实例分享】
一.Android多语言切换 Android应用的开发不可能仅仅针对某一个国家或者区域使用,各国间语言文化各不同样,因此一个优秀的APP必须支持多种语言,为了实现这个特性,Android给出了一个解决 ...
- resize和reserve
resize改变的实际的大小,reserve是容量即capacity 如果先指定capacity的大小,可以防止内存的重新分配,我感觉在分配实际的内存的时候会餐口capacity的大小,如果事先指定容 ...
- [Sdoi2011]火星移民
2283: [Sdoi2011]火星移民 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 119 Solved: 56[Submit][Status] ...
- 《从零开始学Swift》学习笔记(Day 25)——类和结构体定义
原创文章,欢迎转载.转载请注明:关东升的博客 Swift中的类和结构体定义的语法是非常相似的.类使用class关键词定义类,使用struct关键词定义结构体,它们的语法格式如下: class 类名 { ...
- 1400 序列分解(dfs)
1400 序列分解 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 小刀和大刀是双胞胎兄弟.今天他们玩一个有意思的游戏. 大刀给小刀准备了一个长度为n的整数序列.小 ...
- nginx发布的nginScript
nginx发布的nginScript 背景 2015年9月,nginx宣布支持类JavaScript语言.这意味着开发者可以更轻松.自由的控制全球最优秀的HTTP及反向代理服务器,并在此之上可以衍生出 ...
- StartCom免费ssl证书申请以及在Tomcat环境中的配置
提示:建议以下操作不使用谷歌浏览器(该网站的证书不识别...),可以看到我的截图中谷歌换成了ie(没装火狐)...建议该申请使用火狐 前面介绍了下自签名的ssl证书,虽然可以实现https协议访问,但 ...
- Linux下查看CPU型号,内存大小,硬盘空间命令
1 查看CPU 1.1 查看CPU个数 # cat /proc/cpuinfo | grep "physical id" | uniq | wc -l 2 **uniq命令:删除重 ...
- python面试题(七)
1 什么是局域网.广域网.城域网? ①局域网LAN(Local Area Network):一般指覆盖范围在10公里以内,一座楼房或一个单位内部的网络.由于传输距离直接影响传输速度,因此,局域网内的通 ...