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 ...
随机推荐
- array_sum的用法
众所周知,PHP中函数是功能很强大的,那么今天就说下array_sum的功能吧. 函数功能:返回数组中所有值的和. 举例: <?php $a = array(1,2); $b = array_s ...
- FreeMarker / S2SH 各种报错解决方案
1. org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of ...
- 笔记-Android学习历程
1. Junit 配置:在manifest节点下 写入instrumentation,在其兄弟节点下配置application <instrumentation android:name=&qu ...
- c语言 常用知识点
强制类型转换 (int)(x+y) 输入 scanf("a=%f,b=%f",&a,&b); a=1,b=1 char a; a=getchar(); 输入一个字 ...
- Unity3D delegate 用法
delegate:委托机制,不做一一说明: 功能需求1: 音量,为一事件为B: 改变音量如为0,为事件A.也触发事件B: 音量变,所有音乐,如场景,特效,角色,打斗.其所有音量都得变.为C: 思路: ...
- (三)Solrj4到Solrj5的升级之路
(三)Solrj4到Solrj5的升级之路 Solr5发布了,带来了许多激动人心的新特性,但Solrj的许多接口也发生了变化,升级是痛苦的,但也是必须的,下面就赶紧来看看有哪些代码需要升级吧. 变化1 ...
- jQuery 文档操作方法(append)
这些方法对于 XML 文档和 HTML 文档均是适用的,除了:html(). 一.append() 方法 append() 方法在被选元素的结尾(仍然在内部)插入指定内容. 例子: <html& ...
- kafka 集群安装过程
1.下载需要的安装包 http://kafka.apache.org/downloads.html 本文使用的 Scala 2.9.2 - kafka_2.9.2-0.8.2.2.tgz (asc, ...
- Jquery Ajax Json ashx 实现前后台数据传输
经过一个多星期的研究,各种查找资料终于自己实现了Jquery Ajax Json ashx 的前后台数据交流功能 首先一点,Ajax只能对应一个ashx文件,多余两个,如果打开异步传输的async: ...
- 多进程端口监听 How nginx processes a request Server names
网络编程( 六):端口那些事儿 - 知乎专栏 https://zhuanlan.zhihu.com/p/20365900 不停服务reload.restart 多进程端口监听 我们都有一个计算机网络 ...