【Java】实习生面试题及参考答案

如果13*24=400成立,那么使用的是( )运算?

A.四进制
B.六进制
C.九进制
D.十一进制

答案: B

解题思路: --> 采用数学的二元一次方程式 - 设x求解x

(1*x+3)*(2*x+4) = 4*x*x
    (x+3)(2x+4) = 4x^2
 2x^2 +4x+6x+12 = 4x^2
        10x +12 = 2x^2
           5x+6 = x^2
       x^2-5x-6 = 0
     (x-6)(x+1) = 0
最后求解得:x=6 or x=-1

下面哪些是Thread类的方法( )

A. start()    B. run()    C. exit()    D. getPriority()

答案:ABD

解析:看Java API docs吧:http://docs.oracle.com/javase/7/docs/api/,exit()是System类的方法,如System.exit(0)。

下面程序的运行结果:( )

public class Demo {
    public static void main(String[] args) {
        Thread t = new Thread() {
            public void run() {
                pong();
            }
        };
        t.start();
        System.out.print("ping");
    }
    static void pong() {
        System.out.print("pong");
    }
}

A pingpong B pongping C pingpong和pongping都有可能 D 都不输出

答案: A

解析:Thread.start() 只是设定新线程进入 “就绪” 状态,等待 CPU 调度之后才会执行。
而下一个 System.out.print() 几乎(概率大于99%)可以认为是立即接着执行的。
所以,最终效果就是,几乎都是 pingpong。
CPU 执行一条指令的时间,几乎可以忽略,基本是微秒级左右。
CPU 调度切换的时间间隔,基本在毫秒级以上。
这两个时间的比值跟环境有关,但是明显是相当大的(不可能在切换上,消耗太多时间,浪费资源)。
不同的 JAVA 版本,虚拟机,配置,可能效果不一定(编译优化、指令乱序、垃圾回收等等问题)。
但是,主线程的下一条指令,比新线程的第一条指令要快,基本是可以确定的。
没有什么 “随机” 一说

下面程序的运行结果是( )

public class Demo {
    public static void main(String[] args) {
        String str1 = "hello";
        String str2 = "he" + new String("llo");
        System.err.println(str1 == str2);
        System.err.println(str1.equals(str2));
    }
}

答案:false、true

解析:因为str2中的llo是新申请的内存块,而==判断的是对象的地址而非值,所以不一样。如果是String str2 = str1,那么就是true了。
equals() 与 ==
对于基本类型,== 判断两个值是否相等,基本类型没有 equals() 方法。
对于引用类型,== 判断两个变量是否引用同一个对象,而 equals() 判断引用的对象是否等价。

下列说法正确的是()

A. LinkedList继承自List
B. AbstractSet继承自Set
C. HashSet继承自AbstractSet
D. WeakMap继承自HashMap

答案:AC

下列属于关系型数据库的是()

A. Oracle B MySql C IMS D MongoDB

答案:AB

解答:IMS(Information Management System )数据库是IBM公司开发的两种数据库类型之一;
一种是关系数据库,典型代表产品:DB2;
另一种则是层次数据库,代表产品:IMS层次数据库。
非关系型数据库有MongoDB、memcachedb、Redis等。


请你介绍下面向对象的特征

:面向对象有三种特性,封装,继承,多态。
1. 封装可以把软件分隔成一个一个的模块,实现高内聚,低耦合。
2. 继承是子类共享父类的属性和方法的一种机制,提供软件的可重用性和可扩展性。
3. 多态是指不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态。

面向对象和面向过程的区别?

:面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

Java有那些基本数据类型,String是不是基本数据类型,他们有何区别?

:Java基本类型共有八种,基本类型可以分为三类,字符类型char,布尔类型boolean以及数值类型byte、short、int、long、float、double。
String本身就是一个对象而不是基本数据类型,String的变量名是对String类的引用。

this与super有什么区别?

:this是指向当前实例对象,他的一个非常重要的作用就是用来区分对象的成员变量与方法的形参,当一个方法的形参与成员变量的名字相同时就会覆盖成员变量。
super可以用来访问父类的方法或成员变量,当子类的方法或成员变量与父类有相同的名字时也会覆盖父类的方法或成员变量,要想访问父类的方法或成员变量只能通过super关键字来访问。

float型float f=3.4是否正确? 原因?

:不正确。
精度不准确,应该用强制类型转换,float f=(float)3.4float f = 3.4f
在java里面,没小数点的默认是int,有小数点的默认是 double;
int 转成 long 系统自动作没有问题,因为后者精度更高
double 转成 float 就不能自动做了,所以后面的加上个 f;

LinkList和ArrayList的区别(从数据结构说下,以及优缺点)

:他们都是List,都是有序可重复的.

  1. ArrayList底层是数组,查询效率高.插入和删除效率低
  2. LinkList底层是链表,查询效率低.插入和删除效率高.

String类能否被继承 ? 原因?

:不能
String类的方法头是: Public final class String extends Object
之所以不能被继承就是因为其中的修饰关键字 final
其含义相当于C/C++的const,意味着不可修改。
final可以用来修饰 类 、变量 和 方法,
final修饰类的时候 ,这个类就不能被继承了 类中所有的方法也就被隐式的变为final方法
final修饰的方法的类可以被继承,但是final修饰的方法无法被覆写
final修饰的变量相当于常量,只能被赋值一次,赋值后值不再更改 ,这就表示了final修饰的变量必须被初始化,初始化可以在声明变量的时候,也可以在构造函数中初始化

当一个对象被当做参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

:值传递
Java编程语言中只有由值传递参数的。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。

String、StringBuilder、StringBuffer的区别?

  1. 运行速度 :StringBuilder > StringBuffer > String
    原因:String为字符串常量,String对象一旦创建之后该对象是不可更改的。
    Java中对String对象进行的操作实际上是一个不断创建新的对象并且将旧的对象回收的一个过程,所以执行速度很慢。
    StringBuilder和StringBuffer的对象是变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,所以速度要比String快很多。
  2. 在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的
  3. String:适用于少量的字符串操作的情况
    StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
    StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

重载和重写的区别?

  1. 重载(Overload)是让类以统一的方式处理不同类型数据的一种手段,实质表现就是多个具有不同的参数个数或者类型的同名函数(返回值类型可随意,不能以返回类型作为重载函数的区分标准)同时存在于同一个类中,是一个类中多态性的一种表现(调用方法时通过传递不同参数个数和参数类型来决定具体使用哪个方法的多态性)。
  2. 重写(Override)是父类与子类之间的多态性,实质是对父类的函数进行重新定义,如果在子类中定义某方法与其父类有相同的名称和参数则该方法被重写,不过子类函数的访问修饰权限不能小于父类的;若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法,如需父类中原有的方法则可使用 super 关键字。

重载与重写是 Java 多态性的不同表现。
  重写是父类与子类之间多态性的表现,在运行时起作用(动态多态性,譬如实现动态绑定)
  而重载是一个类中多态性的表现,在编译时起作用(静态多态性,譬如实现静态绑定)。

Spring的核心?


Spring的三大核心思想:IOC(控制反转),DI(依赖注入),AOP(面向切面编程)。

  1. IOC(控制反转)
    实现将组件间的关系从程序内部提到外部容器(spring的xml)来管理。
    首先外部容器(spring.xml)中会动态的注册业务所需的对象(接口/类)
  2. DI(依赖注入)
    组件之间的依赖关系由容器在应用系统运行期来决定, 也就是由容器动态地将某种依赖关系的目标对象实例注入到应用 系统中的各个关联的组件之中
  3. AOP(面向切面编程)
    利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。
    使用"横切"技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。

SpringMVC 执行流程?

  1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获(捕获)
  2. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;(查找handler)
  3. DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller), Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象(执行handler)
  4. DispatcherServlet 根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver) (选择ViewResolver)
  5. 通过ViewResolver 结合Model和View,来渲染视图,DispatcherServlet 将渲染结果返回给客户端。(渲染返回)

什么是HashMap?它的底层是怎么实现的?

  1. Jdk1.7中,HashMap底层基于数组+链表实现,如果entry放的位置在数组中都是同一个位置,链表就会变得很长,链表深度过深将导致效率低下!
  2. 因此在Jdk1.8中,为了解决链表深度过深导致的效率低下问题,HashMap底层结构变为数组+链表+红黑树实现。

用 Java 写一个线程安全的单例模式(Singleton)?

简单说一下前后端分离?


简单介绍一下关系数据库三范式?

  1. 第一范式(1NF):列不可分割
  2. 第二范式(2NF):主键
  3. 第三范式(3NF)必须先满足第二范式(2NF)。外键
  4. 反三范式,有的时候为了效率,可以设置重复或者可以推导出的字段

事务四个基本特征或 ACID 特性?

事务必须满足四大特征:原子性,一致性,隔离性,持久性

  1. 原子性:表示事务内操作不可分割。要么都成功、要么都是失败.
  2. 一致性:要么都成功、要么都是失败.后面的失败了要对前面的操作进行回滚。
  3. 隔离性:一个事务开始后,不能后其他事务干扰。
  4. 持久性:表示事务开始了,就不能终止。

char 和 varchar 的区别是什么?

  1. char(n) :固定长度类型,比如订阅 char(10),当你输入"abc"三个字符的时候,它们占的空间还是 10 个字节,其他 7 个是空字节。
    chat 优点:效率高;缺点:占用空间;适用场景:存储密码的 md5 值,固定长度的,使用 char 非常合适。
  2. varchar(n) :可变长度,存储的值是每个值占用的字节再加上一个用来记录其长度的字节的长度。
    所以,从空间上考虑 varchar 比较合适;从效率上考虑 char 比较合适,二者使用需要权衡。

说一下乐观锁和悲观锁?

  1. 乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下在此期间别人有没有去更新这个数据。
  2. 悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻止,直到这个锁被释放。
  3. 数据库的乐观锁需要自己实现,在表里面添加一个 version 字段,每次修改成功值加 1,这样每次修改的时候先对比一下,自己拥有的 version 和数据库现在的 version 是否一致,如果不一致就不修改,这样就实现了乐观锁。

MySQL编程

表名和字段
  1. 学生表 Student(s_id,s_name,s_birth,s_sex) --学生编号,学生姓名, 出生年月,学生性别
  2. 课程表 Course(c_id,c_name,t_id) --课程编号, 课程名称, 教师编号
  3. 教师表 Teacher(t_id,t_name) --教师编号,教师姓名
  4. 成绩表 Score(s_id,c_id,s_score) --学生编号,课程编号,分数
建表+测试数据
--建表
--学生表
CREATE TABLE `Student`(
	`s_id` VARCHAR(20),
	`s_name` VARCHAR(20) NOT NULL DEFAULT '',
	`s_birth` VARCHAR(20) NOT NULL DEFAULT '',
	`s_sex` VARCHAR(10) NOT NULL DEFAULT '',
	PRIMARY KEY(`s_id`)
);
--课程表
CREATE TABLE `Course`(
	`c_id`  VARCHAR(20),
	`c_name` VARCHAR(20) NOT NULL DEFAULT '',
	`t_id` VARCHAR(20) NOT NULL,
	PRIMARY KEY(`c_id`)
);
--教师表
CREATE TABLE `Teacher`(
	`t_id` VARCHAR(20),
	`t_name` VARCHAR(20) NOT NULL DEFAULT '',
	PRIMARY KEY(`t_id`)
);
--成绩表
CREATE TABLE `Score`(
	`s_id` VARCHAR(20),
	`c_id`  VARCHAR(20),
	`s_score` INT(3),
	PRIMARY KEY(`s_id`,`c_id`)
);
--插入学生表测试数据
insert into Student values('01' , '赵雷' , '1990-01-01' , '男');
insert into Student values('02' , '钱电' , '1990-12-21' , '男');
insert into Student values('03' , '孙风' , '1990-05-20' , '男');
insert into Student values('04' , '李云' , '1990-08-06' , '男');
insert into Student values('05' , '周梅' , '1991-12-01' , '女');
insert into Student values('06' , '吴兰' , '1992-03-01' , '女');
insert into Student values('07' , '郑竹' , '1989-07-01' , '女');
insert into Student values('08' , '王菊' , '1990-01-20' , '女');
--课程表测试数据
insert into Course values('01' , '语文' , '02');
insert into Course values('02' , '数学' , '01');
insert into Course values('03' , '英语' , '03');

--教师表测试数据
insert into Teacher values('01' , '张三');
insert into Teacher values('02' , '李四');
insert into Teacher values('03' , '王五');

--成绩表测试数据
insert into Score values('01' , '01' , 80);
insert into Score values('01' , '02' , 90);
insert into Score values('01' , '03' , 99);
insert into Score values('02' , '01' , 70);
insert into Score values('02' , '02' , 60);
insert into Score values('02' , '03' , 80);
insert into Score values('03' , '01' , 80);
insert into Score values('03' , '02' , 80);
insert into Score values('03' , '03' , 80);
insert into Score values('04' , '01' , 50);
insert into Score values('04' , '02' , 30);
insert into Score values('04' , '03' , 20);
insert into Score values('05' , '01' , 76);
insert into Score values('05' , '02' , 87);
insert into Score values('06' , '01' , 31);
insert into Score values('06' , '03' , 34);
insert into Score values('07' , '02' , 89);
insert into Score values('07' , '03' , 98);
问题及sql语句
-- 1、查询"01"课程比"02"课程成绩高的学生的信息及课程分数	
	
select a.* ,b.s_score as 01_score,c.s_score as 02_score from 
student a 
	join score b on a.s_id=b.s_id and b.c_id='01'
	left join score c on a.s_id=c.s_id and c.c_id='02' or c.c_id = NULL where b.s_score>c.s_score
	
-- 也可以这样写
	select a.*,b.s_score as 01_score,c.s_score as 02_score from student 		  a,score b,score c 
			where a.s_id=b.s_id 
			and a.s_id=c.s_id 
			and b.c_id='01' 
			and c.c_id='02' 
			and b.s_score>c.s_score
-- 2、查询"01"课程比"02"课程成绩低的学生的信息及课程分数
	
select a.* ,b.s_score as 01_score,c.s_score as 02_score from 
	student a left join score b on a.s_id=b.s_id and b.c_id='01' or b.c_id=NULL 
	 join score c on a.s_id=c.s_id and c.c_id='02' where b.s_score<c.s_score
			

-- 3、查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩
select b.s_id,b.s_name,ROUND(AVG(a.s_score),2) as avg_score from 
	student b 
	join score a on b.s_id = a.s_id
	GROUP BY b.s_id,b.s_name HAVING avg_score >=60;
	

-- 4、查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩
		-- (包括有成绩的和无成绩的)
		
select b.s_id,b.s_name,ROUND(AVG(a.s_score),2) as avg_score from 
	student b 
	left join score a on b.s_id = a.s_id
	GROUP BY b.s_id,b.s_name HAVING avg_score <60
	union
select a.s_id,a.s_name,0 as avg_score from 
	student a 
	where a.s_id not in (
				select distinct s_id from score);


-- 5、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
select a.s_id,a.s_name,count(b.c_id) as sum_course,sum(b.s_score) as sum_score from 
	student a 
	left join score b on a.s_id=b.s_id
	GROUP BY a.s_id,a.s_name;
			
			
-- 6、查询"李"姓老师的数量 
select count(t_id) from teacher where t_name like '李%';
	
-- 7、查询学过"张三"老师授课的同学的信息 
select a.* from 
	student a 
	join score b on a.s_id=b.s_id where b.c_id in(
		select c_id from course where t_id =(
			select t_id from teacher where t_name = '张三'));

-- 8、查询没学过"张三"老师授课的同学的信息 
select * from 
    student c 
    where c.s_id not in(
        select a.s_id from student a join score b on a.s_id=b.s_id where b.c_id in(
        select a.c_id from course a join teacher b on a.t_id = b.t_id where t_name ='张三'));
-- 9、查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息

select a.* from 
	student a,score b,score c 
	where a.s_id = b.s_id  and a.s_id = c.s_id and b.c_id='01' and c.c_id='02';
	
-- 10、查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息
			
select a.* from 
	student a 
	where a.s_id in (select s_id from score where c_id='01' ) and a.s_id not in(select s_id from score where c_id='02')
			

-- 11、查询没有学全所有课程的同学的信息 
-- @wendiepei的写法
select s.* from student s 
left join Score s1 on s1.s_id=s.s_id
group by s.s_id having count(s1.c_id)<(select count(*) from course)	
-- @k1051785839的写法
select *
from student
where s_id not in(
select s_id from score t1  
group by s_id having count(*) =(select count(distinct c_id)  from course)) 
-- 12、查询至少有一门课与学号为"01"的同学所学相同的同学的信息 

select * from student where s_id in(
	select distinct a.s_id from score a where a.c_id in(select a.c_id from score a where a.s_id='01')
	);
			
-- 13、查询和"01"号的同学学习的课程完全相同的其他同学的信息 
-- @ouyang_1993的写法
SELECT
 Student.*
FROM
 Student
WHERE
 s_id IN (SELECT s_id FROM Score GROUP BY s_id HAVING COUNT(s_id) = (
    #下面的语句是找到'01'同学学习的课程数
    SELECT COUNT(c_id) FROM Score WHERE s_id = '01'
   )
 )
AND s_id NOT IN (
 #下面的语句是找到学过‘01’同学没学过的课程,有哪些同学。并排除他们
 SELECT s_id FROM Score
 WHERE c_id IN(
   #下面的语句是找到‘01’同学没学过的课程
   SELECT DISTINCT c_id FROM Score
   WHERE c_id NOT IN (
     #下面的语句是找出‘01’同学学习的课程
     SELECT c_id FROM Score WHERE s_id = '01'
    )
  ) GROUP BY s_id
) #下面的条件是排除01同学
AND s_id NOT IN ('01')
-- @k1051785839的写法
SELECT
 t3.*
FROM
 (
  SELECT
   s_id,
   group_concat(c_id ORDER BY c_id) group1
  FROM
   score
  WHERE
   s_id &lt;> '01'
  GROUP BY
   s_id
 ) t1
INNER JOIN (
 SELECT
  group_concat(c_id ORDER BY c_id) group2
 FROM
  score
 WHERE
  s_id = '01'
 GROUP BY
  s_id
) t2 ON t1.group1 = t2.group2
INNER JOIN student t3 ON t1.s_id = t3.s_id

-- 14、查询没学过"张三"老师讲授的任一门课程的学生姓名 
select a.s_name from student a where a.s_id not in (
	select s_id from score where c_id = 
				(select c_id from course where t_id =(
					select t_id from teacher where t_name = '张三')));

-- 15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩 
select a.s_id,a.s_name,ROUND(AVG(b.s_score)) from 
	student a 
	left join score b on a.s_id = b.s_id
	where a.s_id in(
			select s_id from score where s_score<60 GROUP BY  s_id having count(1)>=2)
	GROUP BY a.s_id,a.s_name

-- 16、检索"01"课程分数小于60,按分数降序排列的学生信息
select a.*,b.c_id,b.s_score from 
	student a,score b 
	where a.s_id = b.s_id and b.c_id='01' and b.s_score<60 ORDER BY b.s_score DESC;
		
-- 17、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
select a.s_id,(select s_score from score where s_id=a.s_id and c_id='01') as 语文,
				(select s_score from score where s_id=a.s_id and c_id='02') as 数学,
				(select s_score from score where s_id=a.s_id and c_id='03') as 英语,
			round(avg(s_score),2) as 平均分 from score a  GROUP BY a.s_id ORDER BY 平均分 DESC;
-- @喝完这杯还有一箱的写法
SELECT a.s_id,MAX(CASE a.c_id WHEN '01' THEN a.s_score END ) 语文, 
MAX(CASE a.c_id WHEN '02' THEN a.s_score END ) 数学, 
MAX(CASE a.c_id WHEN '03' THEN a.s_score END ) 英语, 
avg(a.s_score),b.s_name FROM Score a JOIN Student b ON a.s_id=b.s_id GROUP BY a.s_id ORDER BY 5 DESC		
-- 18.查询各科成绩最高分、最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率
-- 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
select a.c_id,b.c_name,MAX(s_score),MIN(s_score),ROUND(AVG(s_score),2),
	ROUND(100*(SUM(case when a.s_score>=60 then 1 else 0 end)/SUM(case when a.s_score then 1 else 0 end)),2) as 及格率,
	ROUND(100*(SUM(case when a.s_score>=70 and a.s_score<=80 then 1 else 0 end)/SUM(case when a.s_score then 1 else 0 end)),2) as 中等率,
	ROUND(100*(SUM(case when a.s_score>=80 and a.s_score<=90 then 1 else 0 end)/SUM(case when a.s_score then 1 else 0 end)),2) as 优良率,
	ROUND(100*(SUM(case when a.s_score>=90 then 1 else 0 end)/SUM(case when a.s_score then 1 else 0 end)),2) as 优秀率
	from score a left join course b on a.c_id = b.c_id GROUP BY a.c_id,b.c_name
	
-- 19、按各科成绩进行排序,并显示排名
-- mysql没有rank函数
	select a.s_id,a.c_id,
        @i:=@i +1 as i保留排名,
        @k:=(case when @score=a.s_score then @k else @i end) as rank不保留排名,
        @score:=a.s_score as score
    from (
        select s_id,c_id,s_score from score GROUP BY s_id,c_id,s_score ORDER BY s_score DESC
)a,(select @k:=0,@i:=0,@score:=0)s
-- @k1051785839的写法
(select * from (select 
t1.c_id,
t1.s_score,
(select count(distinct t2.s_score) from score t2 where t2.s_score>=t1.s_score and t2.c_id='01') rank
FROM score t1 where t1.c_id='01'
order by t1.s_score desc) t1)
union
(select * from (select 
t1.c_id,
t1.s_score,
(select count(distinct t2.s_score) from score t2 where t2.s_score>=t1.s_score and t2.c_id='02') rank
FROM score t1 where t1.c_id='02'
order by t1.s_score desc) t2)
union
(select * from (select 
t1.c_id,
t1.s_score,
(select count(distinct t2.s_score) from score t2 where t2.s_score>=t1.s_score and t2.c_id='03') rank
FROM score t1 where t1.c_id='03'
order by t1.s_score desc) t3)
-- 20、查询学生的总成绩并进行排名
select a.s_id,
	@i:=@i+1 as i,
	@k:=(case when @score=a.sum_score then @k else @i end) as rank,
	@score:=a.sum_score as score
from (select s_id,SUM(s_score) as sum_score from score GROUP BY s_id ORDER BY sum_score DESC)a,
	(select @k:=0,@i:=0,@score:=0)s
	
-- 21、查询不同老师所教不同课程平均分从高到低显示 
		
	select a.t_id,c.t_name,a.c_id,ROUND(avg(s_score),2) as avg_score from course a
		left join score b on a.c_id=b.c_id 
		left join teacher c on a.t_id=c.t_id
		GROUP BY a.c_id,a.t_id,c.t_name ORDER BY avg_score DESC;
-- 22、查询所有课程的成绩第2名到第3名的学生信息及该课程成绩
			
			select d.*,c.排名,c.s_score,c.c_id from (
                select a.s_id,a.s_score,a.c_id,@i:=@i+1 as 排名 from score a,(select @i:=0)s where a.c_id='01'  
								ORDER BY a.s_score DESC  
            )c
            left join student d on c.s_id=d.s_id
            where 排名 BETWEEN 2 AND 3
            UNION
            select d.*,c.排名,c.s_score,c.c_id from (
                select a.s_id,a.s_score,a.c_id,@j:=@j+1 as 排名 from score a,(select @j:=0)s where a.c_id='02'  
								ORDER BY a.s_score DESC
            )c
            left join student d on c.s_id=d.s_id
            where 排名 BETWEEN 2 AND 3
            UNION
            select d.*,c.排名,c.s_score,c.c_id from (
                select a.s_id,a.s_score,a.c_id,@k:=@k+1 as 排名 from score a,(select @k:=0)s where a.c_id='03' 
								ORDER BY a.s_score DESC
            )c
            left join student d on c.s_id=d.s_id
            where 排名 BETWEEN 2 AND 3;
			
-- 23、统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所占百分比
		select distinct f.c_name,a.c_id,b.`85-100`,b.百分比,c.`70-85`,c.百分比,d.`60-70`,d.百分比,e.`0-60`,e.百分比 from score a
				left join (select c_id,SUM(case when s_score >85 and s_score <=100 then 1 else 0 end) as `85-100`,
											ROUND(100*(SUM(case when s_score >85 and s_score <=100 then 1 else 0 end)/count(*)),2) as 百分比
								from score GROUP BY c_id)b on a.c_id=b.c_id
				left join (select c_id,SUM(case when s_score >70 and s_score <=85 then 1 else 0 end) as `70-85`,
											ROUND(100*(SUM(case when s_score >70 and s_score <=85 then 1 else 0 end)/count(*)),2) as 百分比
								from score GROUP BY c_id)c on a.c_id=c.c_id
				left join (select c_id,SUM(case when s_score >60 and s_score <=70 then 1 else 0 end) as `60-70`,
											ROUND(100*(SUM(case when s_score >60 and s_score <=70 then 1 else 0 end)/count(*)),2) as 百分比
								from score GROUP BY c_id)d on a.c_id=d.c_id
				left join (select c_id,SUM(case when s_score >=0 and s_score <=60 then 1 else 0 end) as `0-60`,
											ROUND(100*(SUM(case when s_score >=0 and s_score <=60 then 1 else 0 end)/count(*)),2) as 百分比
								from score GROUP BY c_id)e on a.c_id=e.c_id
				left join course f on a.c_id = f.c_id
				 
-- 24、查询学生平均成绩及其名次 

		select a.s_id,
				@i:=@i+1 as '不保留空缺排名',
				@k:=(case when @avg_score=a.avg_s then @k else @i end) as '保留空缺排名',
				@avg_score:=avg_s as '平均分'
		from (select s_id,ROUND(AVG(s_score),2) as avg_s from score GROUP BY s_id ORDER BY avg_s DESC)a,(select @avg_score:=0,@i:=0,@k:=0)b;
-- 25、查询各科成绩前三名的记录
			-- 1.选出b表比a表成绩大的所有组
			-- 2.选出比当前id成绩大的 小于三个的
		select a.s_id,a.c_id,a.s_score from score a 
			left join score b on a.c_id = b.c_id and a.s_score<b.s_score
			group by a.s_id,a.c_id,a.s_score HAVING COUNT(b.s_id)<3
			ORDER BY a.c_id,a.s_score DESC

-- 26、查询每门课程被选修的学生数 

		select c_id,count(s_id) from score a GROUP BY c_id

-- 27、查询出只有两门课程的全部学生的学号和姓名 
		select s_id,s_name from student where s_id in(
				select s_id from score GROUP BY s_id HAVING COUNT(c_id)=2);

-- 28、查询男生、女生人数 
		select s_sex,COUNT(s_sex) as 人数  from student GROUP BY s_sex

-- 29、查询名字中含有"风"字的学生信息

		select * from student where s_name like '%风%';

-- 30、查询同名同性学生名单,并统计同名人数 
		
		select a.s_name,a.s_sex,count(*) from student a  JOIN 
					student b on a.s_id !=b.s_id and a.s_name = b.s_name and a.s_sex = b.s_sex
		GROUP BY a.s_name,a.s_sex

-- 31、查询1990年出生的学生名单
		
		select s_name from student where s_birth like '1990%'

-- 32、查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列 

	select c_id,ROUND(AVG(s_score),2) as avg_score from score GROUP BY c_id ORDER BY avg_score DESC,c_id ASC

-- 33、查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩 

	select a.s_id,b.s_name,ROUND(avg(a.s_score),2) as avg_score from score a
		left join student b on a.s_id=b.s_id GROUP BY s_id HAVING avg_score>=85
	
-- 34、查询课程名称为"数学",且分数低于60的学生姓名和分数 
	
		select a.s_name,b.s_score from score b join student a on a.s_id=b.s_id where b.c_id=(
					select c_id from course where c_name ='数学') and b.s_score<60

-- 35、查询所有学生的课程及分数情况; 
	
		
		select a.s_id,a.s_name,
					SUM(case c.c_name when '语文' then b.s_score else 0 end) as '语文',
					SUM(case c.c_name when '数学' then b.s_score else 0 end) as '数学',
					SUM(case c.c_name when '英语' then b.s_score else 0 end) as '英语',
					SUM(b.s_score) as  '总分'
		from student a left join score b on a.s_id = b.s_id 
		left join course c on b.c_id = c.c_id 
		GROUP BY a.s_id,a.s_name


 -- 36、查询任何一门课程成绩在70分以上的姓名、课程名称和分数; 
			select a.s_name,b.c_name,c.s_score from course b left join score c on b.c_id = c.c_id
				left join student a on a.s_id=c.s_id where c.s_score>=70

		

-- 37、查询不及格的课程
		select a.s_id,a.c_id,b.c_name,a.s_score from score a left join course b on a.c_id = b.c_id
			where a.s_score<60 
		
-- 38、查询课程编号为01且课程成绩在80分以上的学生的学号和姓名; 
		select a.s_id,b.s_name from score a LEFT JOIN student b on a.s_id = b.s_id
			where a.c_id = '01'	and a.s_score>80

-- 39、求每门课程的学生人数 
		select count(*) from score GROUP BY c_id;

-- 40、查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩

		
		-- 查询老师id	
		select c_id from course c,teacher d where c.t_id=d.t_id and d.t_name='张三'
		-- 查询最高分(可能有相同分数)
		select MAX(s_score) from score where c_id='02'
		-- 查询信息
		select a.*,b.s_score,b.c_id,c.c_name from student a
			LEFT JOIN score b on a.s_id = b.s_id
			LEFT JOIN course c on b.c_id=c.c_id
			where b.c_id =(select c_id from course c,teacher d where c.t_id=d.t_id and d.t_name='张三')
			and b.s_score in (select MAX(s_score) from score where c_id='02')


-- 41、查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩 
	select DISTINCT b.s_id,b.c_id,b.s_score from score a,score b where a.c_id != b.c_id and a.s_score = b.s_score
	

-- 42、查询每门功成绩最好的前两名 
		-- 牛逼的写法
	select a.s_id,a.c_id,a.s_score from score a
		where (select COUNT(1) from score b where b.c_id=a.c_id and b.s_score>=a.s_score)<=2 ORDER BY a.c_id


-- 43、统计每门课程的学生选修人数(超过5人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列  
		select c_id,count(*) as total from score GROUP BY c_id HAVING total>5 ORDER BY total,c_id ASC
		
-- 44、检索至少选修两门课程的学生学号 
		select s_id,count(*) as sel from score GROUP BY s_id HAVING sel>=2

-- 45、查询选修了全部课程的学生信息 
		select * from student where s_id in(		
			select s_id from score GROUP BY s_id HAVING count(*)=(select count(*) from course))


-- 46、查询各学生的年龄
	-- 按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一

	select s_birth,(DATE_FORMAT(NOW(),'%Y')-DATE_FORMAT(s_birth,'%Y') - 
				(case when DATE_FORMAT(NOW(),'%m%d')>DATE_FORMAT(s_birth,'%m%d') then 0 else 1 end)) as age
		from student;


-- 47、查询本周过生日的学生
	select * from student where WEEK(DATE_FORMAT(NOW(),'%Y%m%d'))=WEEK(s_birth)
	select * from student where YEARWEEK(s_birth)=YEARWEEK(DATE_FORMAT(NOW(),'%Y%m%d'))
	
	select WEEK(DATE_FORMAT(NOW(),'%Y%m%d'))

-- 48、查询下周过生日的学生
	select * from student where WEEK(DATE_FORMAT(NOW(),'%Y%m%d'))+1 =WEEK(s_birth)

-- 49、查询本月过生日的学生

	select * from student where MONTH(DATE_FORMAT(NOW(),'%Y%m%d')) =MONTH(s_birth)
	
-- 50、查询下月过生日的学生
	select * from student where MONTH(DATE_FORMAT(NOW(),'%Y%m%d'))+1 =MONTH(s_birth)
发布了557 篇原创文章 · 获赞 573 · 访问量 99万+

猜你喜欢

转载自blog.csdn.net/qq_38225558/article/details/103541266