Java面试题——编程题部分
文章目录
- Java面试题——编程题部分
- 1.见题目
- 2.本地有一个存放学生的a.txt文件,内容如下
- 3.请写出对map集合的遍历实现(尽可能写出多种方式)
- 4.在Java中如何获得当前时间,如何转换为某字符串格式
- 5.对数组进行去重
- 6.对集合进行去重
- 7.请写出懒汉式和饿汉式单例模式
- 8.写一段代码删除list中所有结尾数字可被2整除的节点
- 9.如何对List根据age进行排序
- 10.从表t1(有字段`id`、`name`、`sex`、`score`)中取出`sex`为男,`score`列前十名的`name`字段
- 11.基于表user,查出表中第10条到第20条连续分页数据的sql语句
- 12.请描述查询语句中各部分的执行顺序
- 13.表名:stu_score,获取班级的最后一名
- 14.表user,字段有id(非自增,不连续),age,name,sex,addTime。求创建时间(addTime)在`2023-05-22`至`2023-06-12`之间的所有数据
- 15.向user表中添加一条数据,包括创建时间
- 16.有以下表写出sql
- 17.有以下表写出sql
- 18.有以下表写出sql
- 19.有以下表写出sql
- 20.有以下表写出sql
- 21.有以下表写出sql
- 22.按照右侧的结果写出生成右侧结果的sql
- 23.有以下表写出sql
- 24.有以下表写出sql
- 25.有以下guest表写出sql
- 26.有以下表写出sql
- 27.有以下表写出sql
1.见题目
- 将
count
文件用程序读取,并打印在控制台上- 将
count
内的每个编码出现的次数统计出来
- 有多少个
- 每个出现的次数
- 将结果通过
text
或excel
输出到文件
B7151890053952,B7151890053952,B7151890053952,B715189005391880590647,39101880612299,39101880612299,39101880612299,39621353,39101880621353,39101880621353,39101880621353,39101835,B7151890054335,39101880621376,39101880621439,B7151890057151890054598,39101880613720,39101880590256,3910188062105880621288,39101880621058,39101880621117,39101880621388,39121388,39101880621058,B7151890054697,39101880621117,39101889,39101880621388,39101880621058,B7151890054697,39101880621101880590102,39101880590102,39101880590102,B7151890053952
public class Demo01{
public static void main(String[] args) throws IOException{
//1.将count文件用程序读取,并打印在控制台上
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("count源文件.txt")));
String line = null;
while((line = br.readLine()) != null){
System.out.println(line);
}
br.close();
//2.将count内的每个编码出现的次数统计出来 有多少个 每个出现的次数 并将结果写入文件
/*
思路:对文件按照单个字符进行读取,判断读取到的字符是否为 "," 若不是,将其存入StringBuilder,若是将StringBuilder中的内容转换成字符串,即为编码,将编码存入map集合,存的时候判断该编码是否已经存在,若存在,让其该编码的次数进行 +1,若不存在,将该编码存入map,次数设为1
*/
PrintWriter pw = new PrintWriter(new FileOutputStream("result.txt"),true);
Map<String,Integer> map = new HashMap()<>;
StringBuilder sb = new StringBuilder();
//按照单个字符读取数据
InputStreamReader isr = new InputStreamReader(new FileInputStream("count源文件.txt"));
int ch = -1;
while((ch = isr.read()) != -1){
//判断字符是否为 ,
if(ch != ','){
sb.append((char)ch);
}else{
String code = sb.toString();
//判断 code 是否存在于 map中
if(map.containsKey(code)){
map.put(code,map.get(code) + 1);
}else{
map.put(code,1);
}
//清空 StringBuilder
sb.delete(0,sb.length()); //包头不包尾
}
}
String count = "编码的个数为:" + map.size();
System.out.println(count);
pw.println(count);
map.forEach((k,v)->{
String line = "编码:" + k + "出现的次数:" + v;
System.out.println(line);
pw.println(line);
});
isr.close();
pw.close();
}
}
关于IO流:
- 按照流向分:输入流、输出流
- 按照读写单位分:字节流、字符流
- 低级流和高级流:低级流直接面向文件操作,高级流直接面向流
字节流:若操作文件为非文本文件(图片、音频、视频),此时必须选择字节流进行读写
抽象基类:(都是抽象类,不能实例化,只能创建子类对象)
InputStream
OutputStream
文件流:(输入流是读数据,输出流是写数据,参照物不同以内存为标准,从内存输出到文件是写,从文件输入到内存是读)
FileInputStream
构造方法:
FileInputStream(File file){} //通过打开一个到实际文件的连接来创建一个FieInputStream,该文件通过文件系统中的File对象file指定。 FileInputStream(String name){} //通过打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的路径名name指定。
读数据:
read():int //从此输入流中读取一个数据字节,int表示读取到的字节 read(byte[]):int //从目标文件读取字节数组个长度的数据字节 /* 关于字符占用的字节: 如果不涉及任何编码字符集,此时一个字符(中文/英文、数字) 占用2个字节 如果文件的字符集为utf-8,一个英文、数字占用1个字节,一个中文占用3个字节 如果文件的字符集GBK,一个英文、数字占用1个字节,一个中文占用2个字节 */
public static void main(String[] args) throws IOException{ FileInputStream fis = new FileInputStream("a.txt"); // int b = -1; //while((b = fis.read()) != -1){ //单个字节读 byte[] bys = new byte[1024]; int len = -1; while((len = fis.read(bys)) != -1){ //数组个字节读 //System.out.println((char)b); System.out.println(new String(bys,0,len)); } fis.close(); }
FileOutputStream
构造方法:
FileOutputStream(File file){} //创建一个向指定File对象表示的文件中写入数据的文件输出流。 FileOutputStream(String name){} //创建一个向具有指定名称name的文件中写入数据的文件输出流。 FileOutputStream((File file/String name,boolean append){} //若第二个参数值为true,则下次写为追加写入,为false和只写一个参数用法相同
写数据:
write(int): //一次写一个字节,无返回值,失败则抛异常 write(byte[]): //一次写一个字节数组 write(byte[],offset,len): //一次将字节数组中实际有的内容写入文件
public static void main(String[] args) throws IOException{ FileInputStream fis = new FileInputStream("ArrayTest.java"); FileOutputStream fos = new FileOutputStream("copy.java"); //按照单个字节进行复制 /*int by = -1; while((by=fis.read())!=-1){ fos.write(by); } */ //按照字节数组复制 byte[] bys = new byte[20]; int len = -1; //实际读取长度 while((len = fis.read(bys)) != -1){ //数组个字节读 fos.write(bys,0,len)); } fos.close(); fis.close(); }
字节缓冲流:(在文件流的基础上多了缓冲区,提高读写效率)
BufferedInputStream
构造方法:
BufferedInputStream(InputStream){} //创建一个BufferedInputStream并保存其参数,即输出流in,以便将来使用
读数据:
read():int //从此输入流中读取一个数据字节,int表示读取到的字节 read(byte[]):int //从目标文件读取字节数组个长度的数据字节
BufferedOutputStream
构造方法:
BufferedOutputStream(InputStream){}
写数据:
write(int): //一次写一个字节,无返回值,失败则抛异常 write(byte[]): //一次写一个字节数组 write(byte[],offset,len): //一次将字节数组中实际有的内容写入文件
字符流:操作单位是字符,会避免乱码的产生,且读写效率比字节流高,但字符流使用前提是操作的必须是文本文件
抽象基类:(都是抽象类,不能实例化,只能创建子类对象)
Reader
Writer
转换流:
InputStreamReader
构造方法:
InputStreamReader(InputStream in){} //创建一个使用默认字符集的InputStreamReader InputStreamReader(InputStream in,String charsetName){} //创建一个使用指定字符集的InputStreamReader /* 编码: 字符 --> 字节 解码: 字节 --> 字符 */
读数据:
read():int //一次读取一个字符 read(char[]):int //一次读取一个字符数组个字符,返回值表示实际读取的长度
public static void main(String[] args) throws IOException{ InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt")); //按照单个字符读取a.txt中字符并输出 /*int ch = -1; while((ch=isr.read())!=-1){ System.out.println((char) ch); } */ //按照字符数组读取数据 char[] chs = new char[3]; int len = -1; //实际读取长度 while((len = isr.read(chs)) != -1){ //数组个字节读 System.out.println(Arrays.toString(chs)); System.out.println(new String(chs,0,len)); } isr.close(); }
OutputStreamWriter
构造方法:
OutputStreamWriter(OutputStream out){} //创建一个使用默认字符集的OutputStreamWriter OutputStreamWriter(OutputStream out,String charsetName){} //创建一个使用指定字符集的OutputStreamWriter
写数据:
write(int): //一次写一个字符 write(char[],off,len): //写入字符数组的某一部分 高频 write(String,off,len): //写入字符串的某一部分
public static void main(String[] args) throws IOException{ InputStreamReader isr = new InputStreamReader(new FileInputStream("ArrayTest.java")); OutputStreamWriter osr = new OutputStreamWriter(new FileOutputStream("wcopy.java")); //按照单个字符复制 /*int ch = -1; while((ch=isr.read())!=-1){ osw.write(ch); } */ //按照字符数组复制 char[] chs = new char[3]; int len = -1; //实际读取长度 while((len = isr.read(chs)) != -1){ //数组个字节读 osw.write(chs,0,len); } isr.close(); osw.close(); }
字符缓冲流:(按行读写数据)
BufferedReader
构造方法:
BufferedReader(Reader in){} //创建一个使用默认大小输入缓冲区的缓冲字符输入流 BufferedReader(Reader in,int size){} //创建一个使用指定大小输入缓冲区的缓冲字符输入流
读数据:
readLine():String //读取到回车换行就结束,但不会读取回车换行,若读到末尾则返回null
public static void main(String[] args) throws IOException{ //使用字符缓冲流复制文件 BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("Demo01.java"))); PrintWriter pw = new PrintWriter(new FileOutputStream("brcopy.java"),true); //复制 String line = null; while((line = br.readLine())!= null){ pw.println(line); } pw.close(); br.close(); }
BufferedWriter
、PrintWriter
具有自动行刷新功能,默认关闭
构造方法:
PrintWriter(File file/String name){} //创建指定文件创建不具有自动刷新的新的PrintWriter PrintWriter(File file String csn){} //创建具有指定文件和字符集且不具有自动刷新的新的PrintWriter PrintWriter(OutputStream out,boolean autoFlush){} //通过现有的OutputStream创建新的PrintWriter,且带有自动刷新 PrintWriter(Writer out,boolean autoFlush){} //通过现有的Writer创建新的PrintWriter,且带有自动刷新
写数据:
println(String): //自动行刷新 print(String): //自动行刷新不启动
字节流和字符流的选择:
- 字节流:
- 操作的文件是非文本文件
- 需求中分析得出必须按照字节进行读写,此时选择字节流
- 字符流:
- 操作的文件是文本文件
对象流:对对象数据进行读写,对象读写必须序列化
/* 序列化接口: Serializable 叫做标志接口 序列化: 对象数据 --> 字节数据 反序列化: 字节数据 --> 对象数据 反序列化过程: 将文件中读取到的序列版本号与.class文件中的序列版本号进行对比,若相等,则反序列化成功,若不相等,则反序列化失败 序列化版本号: 若实体类中没有序列版本号,则编译时Java为其随机生成版本号,每次编译均重新生成,若实体类中有序列版本号,则后期文件不论如何编译,版本号均不发生改变 idea中设置序列版本号提示步骤: File-->Settings-->Editor-->Inspections-->java-->serialization issues-->勾选 serializab1e without serialversionUID */
ObjectInputSteam
构造方法:
ObjectInputSteam(InputSteam) //创建从InputSteam读取的ObjectInputSteam
读对象数据
readObject():Object
ObjectOutputSteam
构造方法:
ObjectOutputSteam(OutputSteam) //创建写入指定的OutputSteam的ObjectOutputSteam
写对象数据
writeObject(Object)
2.本地有一个存放学生的a.txt文件,内容如下
学号 姓名 性别 年龄 联系电话
11 , 张三, 男 , 23 , 18523214679
12 , 杨丽, 女 , 23 , 15678776678
13 , 小明, 男 , 30 , 13345433451
14 , 小月, 男 , 19 , 18789775567
- 读取
txt
文件的所有内容并显示- 输出所有性别为男的数据
- 对读取到的数据按年龄从大到小输出(忽略第一行)
- 将第三步排序后的数据输出到文件
result.txt
文件中
public class Demo01{
public static void main(String[] args) throws IOException{
//1.读取txt文件的所有内容并显示
//2.输出所有性别为男的数据
//3.对读取到的数据按年龄从大到小输出(忽略第一行)
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("a.txt")));
//3中排序使用 TreeMap
Map<Integer,String> map = new TreeMap<>();
br.readLine(); //忽略第一行
String line = null;
while((line = br.readLine()) != null){
System.out.println(line);
//输出性别为男的数据
String gender = line.split(",")[2].trim();
if("男".equals(gender)){ //equals比较将固定值放在前面
System.out.println(line);
}
//将数据按照年龄降序输出
String ageStr = line.split(",")[3].trim();
int age = Integer.parseInt(ageStr);
map.put(age,line);
}
//将map转换为list,根据value年龄进行降序排列(自定义排序)
List<Map.Entry<String,Integer>> list = new ArrayList<>(map.entrySet());
list.sort((o1,o2)->o2.getValue().compareTo(o1.getValue));
//4.将第三步排序后的数据输出到文件result.txt文件中
PrintWriter pw = new PrintWriter(new FileOutputStream("result.txt"),true);
pw.println(title);
list.forEach(entry->{
String stu = entry.getKey();
System.out.println(stu);
pw.println(stu);
});
pw.close();
br.close();
}
}
3.请写出对map集合的遍历实现(尽可能写出多种方式)
-
for循环
Map<String,Integer> map = new HashMap<>(); for(Map.Entry<String,Integer> entry:map.entrySet()){ System.out.println(entry.getKey() + "-" + entry.getValue()); }
-
lambda表达式
Map<String,Integer> map = new HashMap<>(); map.forEach((k,v)-> System.out.println(k + "-" + v));
-
迭代器
Map<String,Integer> map = new HashMap<>(); Iterator<Map.Entry<String,Integer>> it = map.entrySet().iterator(); while(it.hasNext()){ Map.Entry<String,Integer> entry = it.next(); System.out.println(entry.getKey() + "-" + entry.getValue()); }
4.在Java中如何获得当前时间,如何转换为某字符串格式
LocalDateTime.now(); //格式需要转换 获取当前日期时间
LocalDate.now(); //格式需要转换 获取当前日期,没有时间
new Date(); //格式需要转换
//日期转换类: DateTimeFormatter.ofPattern("");
public static void main(String[] args){
//新日期
//Java8中获取当前日期
LocalDateTime time = LocalDateTime.now();
System.out.println(time);,
//将日期类型转换为某种字符串格式
DateTimeFormatter dtf =
DateTimeFormatter.ofPattern( "yyyy-MM-dd HH : mm : ss" );
String dateStr = dtf.format(time);
System.out.println(dateStr);
//将String类型转换成日期 字符串必须满足Java所识别的日期
String str = "2023-12-12 12:12:12";
LocalDateTime time = LocalDateTime.parse(str,dtf);
System.out.println(time);
//旧日期 Date --> String
Date date = new Date();
SimpleDateFormat sdf =
new SimpleDateFormat("yyyy/MM/dd HH : mm : ss");
String dateStr2 = sdf.format(date);
System.out.println(dateStr2);
//旧日期 String --> Date
String str = "2023/11/11 11:11:11";
try{
Date cur = sdf.parse(str);
System.out.println(cur);
}catch(ParseException e){
e.printStackTrace();
}
}
5.对数组进行去重
int[] ary = {1,2,1,1,1,2,3,4,623,62,2,4,1,0,0};
List<Integer> list = new ArrayList<>();
for(int i:ary){
if(!list,contains(i)){
list.add(i);
}
}
/*
int[] dest = new int[list.size()];
for(int i=0;i<list.size();i++){
dest[i] = list.get(i);
}
*/
Integer[] dest = list.toArray(new Integer[list.size()]);
System.out.println(Arrays.toString(dest));
6.对集合进行去重
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(1);
list.add(4);
list.add(5);
list.add(7);
list.add(1);
list.add(3);
list.add(4);
list.add(5);
List<Integer> list1 = new ArrayList<>();
/*
//以下遍历会产生并发异常 java.util.ConcurrentModificationException
for(Integer i : list){
if(!list1.contains(i)){
list1.add(i);
}else{
list.remove(i);
}
}
*/
//使用迭代器
Iterator<Integer> it = list.iterator();
while(it.hasNext()){
//取出元素
Integer i = it.next();
if(list1.contains(i)){
it.remove();
}else{
list1.add(i);
}
}
System.out.println("去重后的结果为:");
list.forEach(i->System.out.print(i + " "));
7.请写出懒汉式和饿汉式单例模式
//懒汉式
public class SingleTon{
private SingleTon(){}
private static SingleTon singleTon;
public static synchronized SingleTon getInstance(){
if(singleTon == null){
singleTon = new SingleTon();
}
return singleTon;
}
}
//饿汉式
public class SingleTon{
private SingleTon(){}
private static SingleTon singleTon = new SingleTon();
public static SingleTon getInstance(){
return singleTon;
}
}
//饿汉式为什么不加 synchronized,饿汉式是如何保证线程安全的
//对象在类加载时期已经被创建完成,运行期不再创建,多个线程并发访问的是同一个SingleTon
8.写一段代码删除list中所有结尾数字可被2整除的节点
List<String> list = new ArrayList<>();
list.add("aaabbbccc1");
list.add("aaabbbccc2");
list.add("aaabbbccc3");
list.add("aaabbbccc4");
list.add("aaabbbccc5");
list.add("aaabbbccc6");
list.add("aaabbbccc7");
list.add("aaabbbccc8");
//在遍历过程中删除元素,使用迭代器删除
Iterator<Integer> it = list.iterator();
while(it.hasNext()){
String ele = it.next();
//截取数组
int num = Integer.parseInt(ele.substring(9));
if(num%2==0){
it.remove();
}
}
list.forEach(str->System.out.println(str));
9.如何对List根据age进行排序
Collections.sort(list, new Comparator<E>(){
int compare(E o1,E o2){
return o1.getAge().compareTo(o2.getAge());
}
});
list.sort(new Comparator<E>(){
int compare(E o1,E o2){
return o1.getAge().compareTo(o2.getAge());
}
});
10.从表t1(有字段id
、name
、sex
、score
)中取出sex
为男,score
列前十名的name
字段
select name from t1 where sex = '男' order by score desc limit 0,10;
limit
用法:
limit m, n
m
表示查询数据的起始下标,n
表示查询数量
limit n
:从起始位置开始的n
条数据
11.基于表user,查出表中第10条到第20条连续分页数据的sql语句
select * from user limit 9,11
12.请描述查询语句中各部分的执行顺序
select distinct ... from A join B on a.xx=b.xx where xx=? and xx=? group by xx having xx=? order by ... limit m, n
from
:产生虚拟表v1 产生的是笛卡尔积on
:根据连接条件进行筛选,基于v1,产生虚拟表v2left/right join
: 若是外连接,将主表中的所有数据进行补充到v2表中where
:根据查询条件,从v2中进行数据筛选,产生虚拟表v3group by
:对v3分组,产生虚拟表v4having
:对分组后的结果再次筛选,产生虚拟表v5having
是分组后结果进行筛选,没有分组进行筛选使用的是`where``
select
:选择最终要显示的字段,产生虚拟表v6distinct
:对结果集进行去重,产生虚拟表v7order by
:对结果根据某字段进行升序 / 降序排列
13.表名:stu_score,获取班级的最后一名
id | name | score | bj |
---|---|---|---|
1 | 张三 | 82 | 1班 |
2 | 李四 | 64 | 1班 |
3 | 王五 | 98 | 2班 |
4 | 赵六 | 76 | 1班 |
5 | 白七 | 100 | 2班 |
-- 1.求出每个班级的最低分
-- 2.拿刚才的结果表与原表联查,条件为班级号相等同时分数相等,即可以查到每个班的最低分对应的人
select ss.* from stu_score ss join
(select bj,MIN(score) min from stu_score group by bj) tmp
on ss.bj = tmp.bj and ss.score = tmp.min
14.表user,字段有id(非自增,不连续),age,name,sex,addTime。求创建时间(addTime)在2023-05-22
至2023-06-12
之间的所有数据
-- 数据库中的边界值都包括
select * from user where addTime between '2023-05-22' and '2023-06-12';
select * from user where addTime >= '2023-05-22' and addTime <= '2023-06-12';
15.向user表中添加一条数据,包括创建时间
insert into user values(10,21,'tom','男','2023-06-30')
16.有以下表写出sql
student表
sno | sname | sage |
---|---|---|
1 | 张三 | 12 |
2 | 李四 | 14 |
3 | 王五 | 15 |
4 | 赵六 | 18 |
course表
cno | cname |
---|---|
1 | 语文 |
2 | 数学 |
3 | 王五 |
score表
sno | cno | score |
---|---|---|
1 | 1 | 80 |
1 | 2 | 98 |
2 | 1 | 92 |
-
查询所有学生学号、姓名、选课数、总成绩
-- 学生表和成绩表外连接查询,连接条件学号相等 -- 根据学生表的学号进行分组,统计每个学生的总成绩和选课数 SELECT s.sno,sname,COUNT(con),SUM(score) FROM student s LEFT JOIN score sc ON s.sno = sc.sno GROUP BY s.sno
-
查询没有学完所有课程的学生学号、姓名
-- 获取总课程数 select count(*) from course -- 查询成绩表中的课程数小于总课程数,查询每个学生的选课数,筛选选课数 < 总课数 SELECT s.sno,sname FROM student s LEFT JOIN score sc ON s.sno = sc.sno GROUP BY s.sno HAVING COUNT(cno) < (select count(*) from course)
17.有以下表写出sql
student表
id | stu_no | stu_name | stu_gender | class_id |
---|---|---|---|---|
1 | 2023001 | 张三 | 男 | 1 |
2 | 2023002 | 李四 | 男 | 1 |
3 | 2023003 | 王五 | 女 | 2 |
4 | 2023004 | 赵六 | 女 | 3 |
5 | 2023005 | 白七 | 女 | 3 |
class表
id | class_name |
---|---|
1 | 一班 |
2 | 二班 |
3 | 三班 |
score表
stu_id | chinese | math |
---|---|---|
1 | 70 | 80 |
2 | 82 | 98 |
3 | 91 | 92 |
4 | 80 | 90 |
业务场景限制:一个班有多名学生,一名学生只属于一个班级,学生有可能没有成绩
-
查询所有学生的信息(学号、姓名、性别、班级名称)
select stu_no,stu_name,stu_gender,class_name from student s join class c on s.class_id = c.id
-
查询所有人(包括没有成绩的学生)的课程分数(学号、姓名、性别、班级名称、语文分数、数学分数)
select stu_no,stu_name,stu_gender,class_name,chinese,math from student s join class c on s.class_id = c.id left join score sc on sc.stu_id = s.id
-
查询语文分数比“张三”高的学生(学号、姓名、性别、班级名称、语文分数)
select stu_no,stu_name,stu_gender,class_name,chinese from student s join class c on join score sc on sc.stu_id = s.id and s.class_id = c.id where chinese >(select chinese from student s join score sc on s.id = sc.stu_id where stu_name = '张三')
-
查询各科都合格(分数>= 60)的学生(学号、姓名、语文分数、数学分数)
select stu_no,stu_name,chinese,math from student s join score sc on s.id = sc.stu_id where chinese >= 60 and math >= 60
-
查询班级人数 >= 2的班级(班级编号、班级名称、人数)
select s.class_id,class_name,count(stu_no) cou from student s join class c on s.class_id = c.id group by s.class_id having cou >= 2
count() 聚合函数的使用:
- count(*):统计行
- count(col):对这列中的数据进行计数
18.有以下表写出sql
score表
name | course | score |
---|---|---|
张三 | 语文 | 81 |
张三 | 数学 | 79 |
李四 | 数学 | 93 |
王五 | 语文 | 92 |
王五 | 数学 | 88 |
查询每门课程都大于等于80分的学生信息
-- 求出每个学生的最低分,筛选最低分 >= 80 的学生
select name from score group by name having min(score) >= 80
19.有以下表写出sql
student(sno,sname,sage,ssex) 学生表
course(cno,cname,tno) 课程表
sc(sno,cno,score) 成绩表
teacher(tno,tname) 教师表
-
查询课程1的成绩比课程2的成绩高的所有学生的信息
select s.*,sc1.score '课程1',sc2.score '课程2' from sc sc1 join sc sc2 join student s on sc1.sno = sc2.sno and sc1.score > sc2.score and sc1.sno = s.sno where sc1.cno = 1 and sc2.cno = 2
-
查询平均成绩大于60分的同学的学号和平均成绩
select sno,avg(score) av from score group by sno having av > 60
-
查询学过“李四”老师所教课程的所有同学的学号和姓名
select distinct s.sno,sname from teacher t join course c join sc join student s on t.tno = c.tno and c.cno = sc.cno and sc.sno = s.sno where tname = '李四'
-
查询姓“李”的老师的个数
select count(*) from teacher where tname like '李%'
-
查询每门课程的选修人数(课程名称,学生数量)存在没有人选的课程
select cname,count(sno) from course c left join sc on c.cno = sc.cno group by c.cno
-
删除“1002”同学的“1”课程的成绩
delete from sc where sno = 1002 and cno = 1
-
修改tom的年龄为25
update student set sage = 25 where sname = 'tom'
-
查询选修人数最多的课程(课程id,课程名称,学生数量)考虑有多门课程都是选修最多的情况
-- 查询选修人数最多的数目 思路:统计每门课程的选修人数,对人数进行降序排序,筛选第一条数据即为最多的选修人数 select count(sno) cou from sc group by cno order by cou desc limit 1; -- 查询每门课程的选修人数,筛选人数=上述人数的课程 select sc.cno,cname,count(sno) cou from course c join sc on sc.cno = c.cno group by sc.cno having cou = (select count(sno) cou from sc group by cno order by cou desc limit 1)
20.有以下表写出sql
成绩表 student_score
字段名称 | 字段解释 | 字段类型 | 字段长度 |
---|---|---|---|
student_id | 学号 | 字符 | 8 |
student_name | 姓名 | 字符 | 50 |
student_gander | 性别 | 字符(男/女) | 4 |
course_id | 课程号 | 字符 | 5 |
score | 分数 | 数值 | 3 |
is_makeup | 当前考试是否为补考 | 字符(补考:1,非补考:0) | 2 |
课程表 course
字段名称 | 字段解释 | 字段类型 | 字段长度 | 约束 |
---|---|---|---|---|
course_id | 课程号 | 字符 | 5 | PK |
course_name | 课程名 | 字符 | 30 | Not null |
course_desc | 课程介绍 | 字符 | 60 |
-
查询第一次考试后所有需要补考(小于60分)的学生姓名和这门课的名称和成绩
select student_name,course_name,score from student_score ss join course c on c.course_id = ss.course_id where score < 60 and is_makeup = 0
-
查询每个学生第一次考试后需要补考(小于60分)的课程平均分和科目数
-- 筛选第一次考试的成绩不及格数据 -- 针对以上数据,统计每个学生不及格科目数和课程平均分 select student_id,student_name,count(course_id),avg(score) from student_score where is_makeup = 0 and score < 60 group by student_id
-
查询所有参加补考的学生姓名、课程名称、补考成绩和非补考成绩
-- 使用表的自连接查询,从一张成绩表中查询参加了补考的学生信息及补考成绩,到另一个成绩表中查询is_makeup = 0的数据,学号、课程编号均于另一张成绩表中相同的成绩数据 select student_name,course_name,sc1.score,sc2.score from student_score sc1 join student_score sc2 join course c on c.course_id = sc1.course_id and sc1.student_id = sc2.student_id and sc1.course_id = sc2.course_id where sc1.is_makeup = 1 and sc2.is_makeup = 0
21.有以下表写出sql
员工(emp)包含字段编号(emp_no),姓名(emp_name),性别(emp_sex),部门编号(dep_no),部门表(dept)包含字段部门编号(dep_no),部门名称(dep_name),业绩表(salary),包含月份(month),员工编号(emp_no),业绩(salary)
-
获取每个月每个部门的总业绩
select month,d.dept_no,dep_name,sum(salary) from emp join dept join salary on emp.emp_no = salary.emp_no and emp.dep_no = dept.dep_no group by month,dept_no
-
获取每个月每个部门的平均业绩
select month,d.dept_no,dep_name,avg(salary) from emp join dept join salary on emp.emp_no = salary.emp_no and emp.dep_no = dept.dep_no group by month,dept_no
22.按照右侧的结果写出生成右侧结果的sql
-- 先从记录表中根据日期分组,统计出有那些日期
-- 根据分组后的日期到记录表中查询某天胜的场次
-- 根据分组后的日期到记录表中查询某天负的场次
select match_date,
(select count(*) from match_record mr1 where mr1.match_date = mr.match_date and mr1.result = '胜') '胜',
(select count(*) from match_record mr2 where mr2.match_date = mr.match_date and mr2.result = '负') '负'
from match_record mr group by match_date
23.有以下表写出sql
用户表 user
字段名称 | 字段解释 | 字段类型 | 说明 |
---|---|---|---|
id | 编号 | varchar | 主键 |
name | 姓名 | varchar | |
sex | 性别 | varchar | 男女 |
age | 年龄 | int | |
birthday | 出生日期 | date | yyyy-MM-dd |
state | 状态 | int | 1.在职 2.离职 |
角色表 role
字段名称 | 字段解释 | 字段类型 | 说明 |
---|---|---|---|
id | 编号 | varchar | 主键 |
name | 名称 | varchar | |
parentId | 性别 | varchar | 父角色id,根角色null |
remark | 年龄 | varchar |
用户角色关联表 user_role
字段名称 | 字段解释 | 字段类型 | 说明 |
---|---|---|---|
user_id | 学号 | varchar | 联合主键 |
role_id | 姓名 | varchar | 联合主键 |
-
用户表中添加一条数据,请写出SQL语句
insert into user values(1,'tom','男',21,'2023-12-14',1)
-
在用户表中把姓名为"李四"的在职用户的年龄修改为28
update user set age = 28 where name = '李四' and state = 1
-
查询所有的角色名称为"技术人员",性别是女的在职人员
select u.* from role r join user_role ur join user u on r.id = ur.role_id and ur.user_id = u.id where sex = '女' and state = 1 and r.name = '技术人员'
-
把角色名称为"研发人员"的用户"张三"从用户表中删除
delete from user where id in (select u.id from role r join user_role ur join user u on r.id = ur.role_id and ur.user_id = u.id where u.name = '张三' and r.name = '研发人员')
-
查询年龄在18到24岁之间的男性在职人员
select * from user where age between 18 and 24 and sex = '男' and state = 1
-
查询年龄为18,19,20的男性和女性员工的人数,结果如下图所示:
年龄 男 女 18 5 3 19 4 6 20 1 0 select u.age (select count(*) from user u1 where u1.age = u.age and u1.sex = '男') '男', (select count(*) from user u2 where u2.age = u.age and u2.sex = '女') '女', from user u where age between 18 and 20 group by age
-
查询前50名姓“张”男员工
select * from user where name like '张%' and sex = '男' limit 50
-
查询所有根角色员工,根角色就是父角色为null的角色
select u.* from role r join user_role ur join user u on r.id = ur.role_id and ur.user_id = u.id where r.parent_id is null
24.有以下表写出sql
有一张student,包括字段id和name,写出sql,将表中name字段中重复的记录删除,只保留重复数据中id最大的那一条数据
id | name |
---|---|
1 | 张三 |
2 | 张三 |
3 | 李四 |
4 | 王五 |
5 | 王五 |
delete from student where id not in (select max(id) from student group by name)
25.有以下guest表写出sql
账号 | 消费 | 时间 | 金额 | 班次 |
---|---|---|---|---|
accounts | details | date | money | class |
s001 | 房费 | 2023-04-01 | 280 | 001 |
s001 | 酒水 | 2023-06-15 | 120 | 001 |
s001 | 房费 | 2023-08-27 | 300 | 003 |
s002 | 房费 | 2023-04-02 | 50 | |
s003 | 酒水 | 2023-07-25 | 180 | 002 |
s004 | 房费 | 2023-03-21 | 230 | |
s005 | 房费 | 2023-04-19 | 280 | 001 |
s005 | 酒水 | 2023-06-28 | 120 |
-
查询出房费都大于200的账号
-- 筛选出所有的房费数据 -- 对以上数据根据账号进行分组,统计每个账号的房费最低消费金额 -- 对以上数据进行再次筛选,筛选最低房费金额 > 200 的账号 select accounts from guest where detail = '房费' group by accounts having min(money) > 200
-
查询出4月份每个账号酒水和房费的总金额
-- 筛选出4月份的数据 -- 对以上数据根据账号进行分组,统计每个账号4月份中消费的总金额 select accounts,sum(money) from guest where date between '2023-04-01' and '2023-04-30' group by accounts select accounts,sum(money) from guest where month(date) = 1 group by accounts /* 使用mysql提供的日期函数 year(col) --获取该列中日期的年份的值 month(col) --获取该列中日期的月份的值 day(col) --获取该列中日期的天数 date(col) --获取日期中的年月日 hour(col) --获取小时 minute(col) --获取分钟 second(co1) --获取秒数 */
-
将不是房费的班次都改为‘001’
update guest set class= '001' where details != '房费'
-
查询出消费都大于100的账号
-- 选择每个账号最低消费金额大于100的 -- 先查询每个账号的最低消费金额,然后筛选最低消费金额大于100 select accounts from guest group by accounts having min(money) > 100
26.有以下表写出sql
员工表(emp)包含字段员工编号(empno),姓名(ename),工作岗位(job),上级领导编号(mgr),雇佣日期(hiredate),薪资(sal),佣金(comm),部门编号(deptno)
部门表(dept)包含字段部门编号(deptno),部门名称(dname),地点(loc)
-
列出在每个部门工作的员工数量,平均工资
-- 列出部门表和员工表进行外连接查询,部门表为主表 -- 根据部门表的dept_no 分组,统计员工数据(对empno使用count()),部门的平均工资(avg(sal+comm)) select d.deptno,dname,count(empno),avg(sal+comm) from dept d left join emp e on e.deptno = d.deptno group by d.deptno
-
列出所有员工的姓名,部门名称和工资
select ename,dname,sal+comm '工资' from emp e join dept d on e.deptno = d.deptno
-
列出所有部门的详细信息和部门人数
select d.*,count(empno) from dept d left join emp e on e.deptno = d.deptno group by d.deptno
-
列出各种工作的最低工资
select job,min(sal+comm) from emp group by job
-
列出各个部门的manager的最低薪金(若是manager,其job的值为manageer)
select e.deptno,dname,min(sal) from dept d join emp e on e.deptno = d.deptno where job = 'manager' group by e.deptno
-
列出受雇日期早于其直接上级的所有员工
select e.*,mgr.hiredate from emp e join emp mgr on e.mgr = mgr.empno where e.hiredate < mgr.hiredate
-
列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门
select dname,e.* from dept d left join emp e on e.deptno = d.deptno order by dname
-
列出所有’clerk’(办事员)岗位的姓名以及部门名称
select ename,dname from emp e join dept d on e.deptno = d.deptno where job = 'clerk'
-
列出最低薪资大于6500的各种工作
select job from emp group by job having min(sal) > 6500
-
列出在研发部工作的员工姓名,假定不知道研发部的部门编号
select ename from dept d join emp e on e.deptno = d.deptno where dname = '研发部'
27.有以下表写出sql
-
查询“语文”课程比“数学”课程成绩高的学生的性别及课程分数
-- 查询语文成绩 select sc.* from course c join score sc on c.c_id = sc.c_id where c_name = '语文' -- 查询数学成绩 select sc.* from course c join score sc on c.c_id = sc.c_id where c_name = '数学' -- 以上两表和学生表进行连接查询,查询对应的学生数据(3表联查) select s.s_id,s_sname,s_sex,chinese.s_score '语文分',math.s_score '数学分' from student s join (select sc.* from course c join score sc on c.c_id = sc.c_id where c_name = '语文') chinese join (select sc.* from course c join score sc on c.c_id = sc.c_id where c_name = '数学') math on chinese.s_id = math.s_id and chinese.s_score > math.s_score and s.s_id = math.s_id
-
查询“语文”课程比“数学”课程成绩低的学生的性别及课程分数
select s.s_id,s_sname,s_sex,chinese.s_score '语文分',math.s_score '数学分' from student s join (select sc.* from course c join score sc on c.c_id = sc.c_id where c_name = '语文') chinese join (select sc.* from course c join score sc on c.c_id = sc.c_id where c_name = '数学') math on chinese.s_id = math.s_id and chinese.s_score < math.s_score and s.s_id = math.s_id
-
查询平均成绩大于等于60分的学生的学生编号和学生姓名和平均成绩
select s.s_id,s_name, avg(s_score) av from score sc join student s on sc.s_id=s.s_id group by sc.s_id having av >= 60
-
查询平均成绩小于60分的学生的学生编号和学生姓名和平均成绩(包括有成绩和无成绩)
-- 求出每个学生的总分 / 课程总数 = 平均分 然后筛选平均分 < 60 学生 select s.s_id,s_name,sum(s_score)/(select count(*) from course) av from student s join score sc on s.s_id = sc.s_id group by sc.s_id having av < 60
-
查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
select s.s_id,s_name,count(c_id),sum(s_score) from student s left join score sc on s.s_id = sc.s_id group by s.s_id
-
查询“王”姓老师的数量
select count(*) from teacher where t_name like '王%'
-
查询学过“张三”老师授课的同学的信息
select distinct s.* from teacher t join course c join score sc join student s on t.t_id = c.t_id and c.c_id = sc.c_id and sc.s_id = s.s_id where t_name = '张三'
-
查询学过编号为“01”且也学过编号”02“课程的同学的信息
select s.* from score sc1 join score sc2 join student s on sc1.s_id = sc2.s_id and sc1.s_id=s.s_id where sc1.c_id = '01'and sc2.c_id = '02'
-
按平均成绩从高到低显示所有学生的所有课程的成绩及平均成绩
-- 先求出每个学生的平均分(总分 / 课程总数) - 要求所有学生均要查,使用外连接查询 select s.s_id,s_name,sum(s_score) / (select count(*) from course) av, (select sc1.s_score from score sc1 where sc1.c_id = '01' and sc1.s_id = s.s_id) '语文', (select sc2.s_score from score sc2 where sc1.c_id = '02' and sc2.s_id = s.s_id) '数学', (select sc3.s_score from score sc3 where sc1.c_id = '03' and sc3.s_id = s.s_id) '英语', from student s left join score sc on s.s_id = sc.s_id group by s.s_id order by av desc
-
课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率
优秀率(及格为:>=60,中等为:70-80,优良为:80-90,优秀为:>=90)sum (case when s_score >= 60 then 1 else 0 end) / count(s_id) select c.c_id,c_name,max(s_score) '最高分',min(s_score) '最低分',avg(s_score) '平均分', sum (case when s_score >= 60 then 1 else 0 end) / count(s_id) '及格率', sum (case when s_score >= 70 and s_score < 80 then 1 else 0 end) / count(s_id) '中等率', sum (case when s_score >= 80 and s_score < 90 then 1 else 0 end) / count(s_id) '优良率', sum (case when s_score >= 90 then 1 else 0 end) / count(s_id) '优秀率' from course c left join score sc on c.c_id = sc.c_id group by c.c_id
-
查询每门科目成绩都在60分及以上的学生id,姓名,成绩
select s.s_id,s_name , sc1.s_score'语文',sc2.s_score'数学' , sc3.s_score'英语' from score sc1 join score sc2 join score sc3 join student s on sc1.s_id = sc2.s_id and sc2.s_id = sc3.s_id and sc3.s_id = s.s_id where sc1.c_id = '01' and sc1.s_score >= 60 and sc2.c_id = '02' and sc2.s_score >= 60 and sc3.c_id = '03' and sc3.s_score >= 60
-
查询至少有一门科目成绩在90分及以上的学生id,姓名,成绩
select s.s_id,s_name, (select from score sc1 where sc1.c_id = '01' and sc1.s_id = s.s_id) '语文', (select from score sc2 where sc2.c_id = '02' and sc2.s_id = s.s_id) '数学', (select from score sc3 where sc3.c_id = '03' and sc3.s_id = s.s_id) '英语' from score sc join student s on sc.s_id = s.s_id group by sc.s_id having max(s_score) >=90
-
查询所有科目成绩总和在240分及以上的学生id,姓名,和成绩总和,降序排列
select s.s_id,s_name,SUM(s_score) sum from score sc join student s on sc.s_id = s.s_id group by sc.s_id having sum >= 240 order by sum desc
-
查询每个科目成绩最高的学生的学生id,姓名,写在一个表上
create table t as select s.s_id,s_name,tmp.c_id,max from score sc join student s join (select c_id,MAX(s_score) max from score group by c_id) tmp on sc.c_id = tmp.c_id and sc.s_score = tmp.max and s.s_id = sc.s_id
-
查询每个科目成绩最低的学生的学生id,姓名
select s.s_id,s_name,tmp.c_id,min from score sc join student s join (select c_id,min(s_score) min from score group by c_id)tmp on sc.c_id = tmp.c_id and sc.s_score = tmp.min and sc.s_id = s.s_id
-
查询目前没有安排课程的老师的姓名
-- 查询每个老师的课程数,筛选课程数为0的 -- 方式1: 查询教课数为0的老师 select t.t_id,t_name from teacher t left join course c on t.t_id = c.t_id group by t.t_id having count(c_id) = 0 -- 方式2: 两表外联查询c_id为null的数据 select t_name from teacher t left join course c on t.t_id = c.t_id where c_id is null
-
将之前老师表的英文名字转化为大写
update teacher set t_name = upper(t_name)
-
查询每门课程最好的前两名
-- 统计每个学生每门课程比其分数高的人数,筛选比其分数高的人数<2的数据,即当前这个学生是这门课程中的前2名 select sc1.s_id,s_name,sc1.c_id,sc1.s_score from score sc1 join student s on sc1.s_id = s.s_id left join score sc2 on sc1.c_id = sc2.c_id and sc2.s_score > sc1.s_score group by sc1.s_id,sc1.c_id having count(sc2.s_id)<2 order by sc1.c_id
-
统计各科成绩各分数段人数,课程编号,课程名称,【100-85】【85-70】【70-60】【60-0】及所占百分比
select c.c_id,c_name, sum(case when s_score < 60 then 1 else 0 end) '[0-60]', sum(case when s_score >= 60 and s_score < 70 then 1 else 0 end) '[60-70]', sum(case when s_score >= 70 and s_score < 85 then 1 else 0 end) '[70-85]', sum(case when s_score >= 85 then 1 else 0 end) '[85-100]', sum(case when s_score < 60 then 1 else 0 end) / count(s_id) '不及格率', sum(case when s_score >= 60 and s_score < 70 then 1 else 0 end) / count(s_id) '中等率', sum(case when s_score >= 70 and s_score < 85 then 1 else 0 end) / count(s_id) '良好率', sum(case when s_score >= 85 then 1 else 0 end) / count(s_id) '优秀率', from course c left join score sc on c.c_id = sc.c_id group by c.c_id
-
查询学生表中的姓名重复的姓名
select s_name from student group by s_name having count(*) > 1
-
查询学生表中的姓名重复的所有学生信息
select * from student where s_name in (select s_name from student group by s_name having count(*) > 1)