主要思路:
- collect方法进行表关联
- 先关联再查询计算
- 输出之前先用map变形,然后直接输出元组比较方便
- 元组里包含多个数组(常见于groupBy之后的Map里),可用zip关联起来合并为一个数组
import scala.io.Source
object stu {
def main(args: Array[String]): Unit = {
//元组格式的各个表
val course = Source.fromFile("D:\\JavaProjects\\ClassStudy\\Scala\\scalatest\\files\\04student\\course.txt").getLines().toArray.map(x => {
var y = x.split("\t")
(y(0).toInt, y(1), y(2).toInt)
})
val score = Source.fromFile("D:\\JavaProjects\\ClassStudy\\Scala\\scalatest\\files\\04student\\score.txt").getLines().toArray.map(x => {
var y = x.split("\t")
(y(0).toInt, y(1).toInt, y(2).toInt)
})
val student = Source.fromFile("D:\\JavaProjects\\ClassStudy\\Scala\\scalatest\\files\\04student\\student.txt").getLines().toArray.map(x => {
var y = x.split("\t")
(y(0).toInt, y(1), y(2), y(3))
})
val teacher = Source.fromFile("D:\\JavaProjects\\ClassStudy\\Scala\\scalatest\\files\\04student\\teacher.txt").getLines().toArray.map(x => {
var y = x.split("\t")
(y(0).toInt, y(1))
})
println("---第1-2题-----------------")
score.map(x=>{
student.collect({
case i if i._1==x._1=>(i._2,x._2,x._3)
})
}).flatten.filter(_._2<=2).groupBy(_._1).filter(_._2.length==2).filter(x=>x._2(0)._3!=x._2(1)._3).
mapValues(x=>((x.map(y=>y._2).sortWith(_>_),x.map(y=>y._3)),x(0)._3>x(1)._3)).
toArray.map(x=>(x._1,x._2._1._1.zip(x._2._1._2),x._2._2)).
map(x=>(x._2.map(y=>(x._1,y._1,y._2,x._3)))).foreach(x=>x.foreach(println(_)))
println("---第1题-----------------")
//1、查询"01"课程比"02"课程成绩高的学生的信息及课程分数:
val rst1 = score.sortWith(_._1 < _._1).filter(_._2 <= 2).groupBy(_._1).filter(x => x._2.count(x => x._1 == x._1) == 2).
filter(x => x._2(1)._3 > x._2(0)._3).toArray.map(_._2)
for (elem <- rst1) {
student.collect({
case i if i._1 == elem(0)._1 => elem.foreach(x => println((i._2, x._2, x._3)))
})
}
println("---第2题-----------------")
//2.查询"01"课程比"02"课程成绩低的学生的信息及课程分数:
val rst2 = score.sortWith(_._1 < _._1).filter(_._2 <= 2).groupBy(_._1).filter(x => x._2.count(x => x._1 == x._1) == 2).
filter(x => x._2(1)._3 < x._2(0)._3).toArray.map(_._2)
for (elem <- rst2) {
student.collect({
case i if i._1 == elem(0)._1 => elem.foreach(x => println((i._2, x._2, x._3)))
})
}
println("---第3题-----------------")
//3.查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩:
for (elem <- score.groupBy(x => x._1).toArray.
map(x => (x._1, x._2.map(x => x._3).sum / x._2.map(x => x._3).size)).
filter(x => x._2 >= 60).sortWith(_._1 < _._1)) {
student.collect({
case i if i._1 == elem._1 => println((elem._1, elem._2, i._2))
})
}
println("---第4题-----------------")
//4.查询平均成绩小于 60 分的同学的学生编号和学生姓名和平均成绩:
// -(包括有成绩的和无成绩的)
for (elem <- score.groupBy(x => x._1).toArray.
map(x => (x._1, x._2.map(x => x._3).sum / x._2.map(x => x._3).size)).
filter(x => x._2 < 60).sortWith(_._1 < _._1)) {
student.collect({
case i if i._1 == elem._1 => println((elem._1, elem._2, i._2))
})
}
println("---第5题-----------------")
//5.查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩:
for (elem <- score.groupBy(_._1).toArray.
map(x => (x._1, x._2.map(x => x._3).size, x._2.map(x => x._3).sum)).sortWith(_._1 < _._1)) {
student.collect({
case i if i._1 == elem._1 => println((i._1, i._2, elem._2, elem._3))
})
}
println("---第6题-----------------")
//6.查询"李"姓老师的数量:
println(teacher.map(x => {
if (x._2.startsWith("李")) {
1
} else {
0
}
}).sum)
println("---第7题-----------------")
//7.查询学过"张三"老师授课的同学的信息:
score.groupBy(x => x._2).toArray.map(elem =>
elem._2.collect({
case i if i._2 == course.collect({
case j if j._3 == teacher.filter(_._2 == "张三").map(_._1).head => j._1
}).head => student.collect({
case k if k._1 == i._1 => val stu = (k._1, k._2, k._3, k._4, i._2); println(stu)
})
}))
println("---第8题-----------------")
//8.查询没学过"张三"老师授课的同学的信息:
val rst8 = score.groupBy(x => x._2).toArray.map(elem =>
elem._2.collect({
case i if course.collect({
case j if j._3 == teacher.filter(_._2 == "张三").map(_._1).head => j._1
}).contains(i._2) => student.collect({
case k if k._1 == i._1 => val stu = (k._1, k._2, k._3, k._4); stu
})
})).flatten.flatten
student.diff(rst8).foreach(x => println(x))
println("---第9题-----------------")
//9.查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息:
for (elem <- score.filter(_._2 <= 2).groupBy(_._1).toArray.filter(x => x._2.length == 2).
sortWith(_._1 < _._1)) {
student.collect({
case i if i._1 == elem._1 => println((i._1, i._2, i._3, i._4))
})
}
println("---第10题-----------------")
//10.查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息:
for (elem <- score.filter(_._2 <= 2).groupBy(_._1).toArray.filter(x => x._2.length == 1).filter(x => x._2.map(x => x._2).last == 1).
sortWith(_._1 < _._1)) {
student.collect({
case i if i._1 == elem._1 => println((i._1, i._2, i._3, i._4))
})
}
println("---第11题-----------------")
//11、查询没有学全所有课程的同学的信息:
for (elem <- score.groupBy(_._1).toArray.filter(x => x._2.length < 3)) {
student.collect({
case i if i._1 == elem._1 => println((i._1, i._2, i._3, i._4))
})
}
println("---第12题-----------------")
//12、查询至少有一门课与学号为"01"的同学所学相同的同学的信息:
for (elem <- score.groupBy(_._1).toArray.map(x => (x._1, x._2.map(x => x._2))).sortWith(_._1 < _._1)) {
score.groupBy(_._1).toArray.filter(_._1 == 1).map(x => (x._1, x._2.map(x => x._2))).collect({
case i if i._2.intersect(elem._2).length >= 1 => student.collect({
case j if j._1 == elem._1 => println((j._1, j._2, j._3, j._4))
})
})
}
println("---第13题-----------------")
//13、查询和"01"号的同学学习的课程完全相同的其他同学的信息:
for (elem <- score.groupBy(_._1).toArray.map(x => (x._1, x._2.map(x => x._2)))) {
score.groupBy(_._1).toArray.filter(_._1 == 1).map(x => (x._1, x._2.map(x => x._2))).collect({
case i if i._2.intersect(elem._2).length == i._2.length => student.collect({
case j if j._1 == elem._1 => println((j._1, j._2, j._3, j._4))
})
})
}
println("---第14题-----------------")
//14、查询没学过"张三"老师讲授的任一门课程的学生姓名:
//是不是和第8题一模一样???
val rst14 = score.groupBy(x => x._2).toArray.flatMap(elem =>
elem._2.collect({
case i if course.collect({
case j if j._3 == teacher.filter(_._2 == "张三").map(_._1).head => j._1
}).contains(i._2) => student.collect({
case k if k._1 == i._1 => val stu = (k._1, k._2, k._3, k._4); stu
})
})).flatten
student.diff(rst14).foreach(x => println(x))
println("---第15题-----------------")
//15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩:
score.filter(_._3<60).groupBy(_._1).toArray.filter(x=>x._2.length>=2).map(x=>{
student.collect({
case i if i._1==x._1 =>println((i._1,i._2,x._2.map(x=>x._3).sum/x._2.map(x=>x._3).length))
})
})
println("---第16题-----------------")
//16、检索"01"课程分数小于 60,按分数降序排列的学生信息:
score.filter(x=>x._2==1&&x._3<60).sortWith(_._3>_._3).map(x=>{
student.collect({
case i if i._1==x._1 =>println((i._1,i._2,i._3,i._4))
})
})
println("---第17题-----------------")
//17、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩:
//元组里的数组展开时,用flatMap
score.groupBy(_._1).toArray.map(x=>(x._1,x._2.map(x=>(x._1,x._2,x._3)),x._2.map(x=>x._3).
sum/x._2.map(x=>x._3).length)).flatMap(y=>y._2.map(x=>(x._1,x._2,x._3,y._3))).sortWith(_._4>_._4).map(x=>{
student.collect({
case i if i._1==x._1 => (x._1, i._2, x._2, x._3, x._4)
}).map(k=>{
course.collect({
case j if k._3==j._1 => println((k._1,k._2,k._3,j._2,k._4,k._5))
})
})
})
//(k._1, k._2, k._3, j._2, k._4, k._5)
println("---第18题-----------------")
//18.查询各科成绩最高分、最低分和平均分:以如下形式显示:
// 课程 ID,课程 name,最 高分,最低分,平均分,及格率60,中等率70,优良率80,优秀率90:
score.groupBy(_._2).toArray.map(x=>(x._1,x._2.map(y=>y._3).max,x._2.map(y=>y._3).min,
x._2.map(y=>y._3).sum/x._2.length,(x._2.count(_._3>=60)*1.0/x._2.length).formatted("%.2f"),(x._2.count(_._3>=70)*1.0/x._2.length).formatted("%.2f"),
(x._2.count(_._3>=80)*1.0/x._2.length).formatted("%.2f"),(x._2.count(_._3>=90)*1.0/x._2.length).formatted("%.2f"))).map(x=>{
course.collect({
case i if i._1==x._1 => println((x._1, i._2, x._2, x._3, x._4, x._5, x._6, x._7, x._8))
})
})
println("---第19题-----------------")
//19、按各科成绩进行排序,并显示排名:
score.groupBy(_._2).mapValues(x=>x.sortWith(_._3>_._3).zipWithIndex.map(x=>(x._1,x._2+1))).toArray.
map(x=>(x._2.map((y=>y._1._1)),x._2.map((y=>y._1._2)),x._2.map((y=>y._1._3)),x._2.map((y=>y._2)))).
map(x=>x._2.zip(x._1).zip(x._3).zip(x._4)).foreach(x=> x.foreach(y=> println(y)))
println("---第20题-----------------")
//20、查询学生的总成绩并进行排名:
score.groupBy(_._1).toArray.map(x=>(x._1,x._2.map(y=>y._3).sum)).sortWith(_._2>_._2).
zipWithIndex.map(x=>(x._1,x._2+1)).foreach(x=> println(x))
println("---第21题-----------------")
//21、查询不同老师所教不同课程平均分从高到低显示:
score.groupBy(_._2).toArray.map(x=>(x._1,x._2.map(y=>y._3).sum,x._2.map(y=>y._3).length)).map(x=>{
course.collect({
case i if i._1==x._1 => (x._1, i._2, x._2,i._3,x._3)
})
}).flatten.map(x=>{
teacher.collect({
case i if i._1==x._4 => (i._2, x._2, (x._3*1.0/x._5).formatted("%.2f"))
})
}).flatten.foreach(x=> println(x))
println("---第22题-----------------")
//22、查询所有课程的成绩第 2 名到第 3 名的学生信息及该课程成绩:
score.map(x=>{
student.collect({
case i if i._1==x._1 => (i._1,i._2,i._3,i._4,x._2,x._3)
})
}).flatten.map(x=>{
course.collect({
case i if i._1==x._5 => (x._1,x._2,x._3,x._4,x._5,i._2,x._6)
})
}).flatten.groupBy(_._5).map(x=>(x._1,x._2.map(y=>y).sortWith(_._7>_._7).zipWithIndex)).
map(x=>(x._2.map(y=>(y._1._1,y._1._2,y._1._3,y._1._4,y._1._5,y._1._6,y._1._7,y._2+1)).
filter(x=>x._8<=3&&x._8>=2))).foreach(x=>x.foreach(y=> println(y)))
println("---第23题-----------------")
//23、统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所 占百分比
score.map(x=>{
course.collect({
case i if i._1==x._2 =>(x._2,i._2,x._3)
})
}).flatten.groupBy(_._1).toArray.map(x=>(x._2.map(y=>(y._1,y._2,
x._2.map(y=>y._3 ).count(_>=85),
x._2.map(y=>y._3 ).count(z=>z<85&&z>=70),
x._2.map(y=>y._3 ).count(z=>z<70&&z>=60),
x._2.map(y=>y._3 ).count(_<60),
(x._2.map(y=>y._3 ).count(_>=85)*1.0/x._2.map(y=>y._3 ).length).formatted("%.2f"),
(x._2.map(y=>y._3 ).count(z=>z<85&&z>=70)*1.0/x._2.map(y=>y._3 ).length).formatted("%.2f"),
(x._2.map(y=>y._3 ).count(z=>z<70&&z>=60)*1.0/x._2.map(y=>y._3 ).length).formatted("%.2f"),
(x._2.map(y=>y._3 ).count(_<60)*1.0/x._2.map(y=>y._3 ).length).formatted("%.2f"))))).flatten.distinct.
foreach(println(_))
println("---第24题-----------------")
//24、查询学生平均成绩及其名次:
score.map(x=>{
student.collect({
case i if i._1==x._1=> (x._1,i._2,x._3)
})
}).flatten.groupBy(x=>(x._1,x._2)).mapValues(x=>x.map(y=>y._3).sum/x.map(y=>y._3).length).
toArray.map(x=>(x._1._1,x._1._2,x._2)).sortWith(_._3>_._3).zipWithIndex.
map(x=>(x._1._1,x._1._2,x._1._3,x._2+1)).foreach(println(_))
println("---第25题-----------------")
//25、查询各科成绩前三名的记录
score.map(x=>{
student.collect({
case i if i._1==x._1 =>(x._1,i._2,x._2,x._3)
})
}).flatten.map(x=>{
course.collect({
case i if i._1==x._3 =>(x._1,x._2,x._3,i._2,x._4)
})
}).flatten.groupBy(x=>(x._3,x._4)).mapValues(x=>x.map(y=>(y._1,y._2,y._5)).
sortWith(_._3>_._3).zipWithIndex.map(x=>(x._1._1,x._1._2,x._1._3,x._2+1)).filter(_._4<=3)).
map(x=>(x._2.map(y=>(x._1,y._1,y._2,y._3,y._4)))).flatten.foreach(println(_))
println("---第26题-----------------")
//26、查询每门课程被选修的学生数:
score.map(x=>{
course.collect({
case i if i._1==x._2 =>i._2
})
}).flatten.groupBy(x=>x).mapValues(x=>x.length).foreach(println(_))
println("---第27题-----------------")
//27、查询出只有两门课程的全部学生的学号和姓名:
score.map(x=>{
student.collect({
case i if i._1==x._1=>(x._1,i._2,x._2)
})
}).flatten.groupBy(x=>(x._1,x._2)).mapValues(x=>x.length).
filter(_._2==2).foreach(println(_))
println("---第28题-----------------")
//28、查询男生、女生人数:
student.groupBy(_._4).mapValues(_.length).foreach(println(_))
println("---第29题-----------------")
//29、查询名字中含有"风"字的学生信息:
student.filter(_._2.contains("风")).foreach(println(_))
println("---第30题-----------------")
//30、查询同名同性学生名单,并统计同名人数:
//同名
student.groupBy(_._2).filter(x=>x._2.length>1).mapValues(_.length).foreach(println(_))
//同名同性别
student.groupBy(x=>(x._2,x._4)).filter(x=>x._2.length>1).mapValues(_.length).foreach(println(_))
}
}
println("---第31题-----------------")
// 31、查询 1990 年出生的学生名单:
// student.filter(x=>x._3.substring(0,4).compareTo("1990")==0).foreach(println(_))
// student.filter(x=>x._3.substring(0,4).equals("1990")).foreach(println(_))
student.filter(x=>x._3.substring(0,4).toInt==1990).foreach(println(_))
println("---第32题-----------------")
// 32、查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时, 按课程编号升序排列:
score.groupBy(_._2).mapValues(x=>(x.map(y=>y._3).sum*1.0/x.map(y=>y._3).length).formatted("%.2f").distinct).
toArray.sortWith(_._1<_._1).sortWith(_._2>_._2).map(x=>{
course.collect({
case i if i._1==x._1=>(x._1,i._2,x._2)
})
}).flatten.foreach(println(_))
println("---第33题-----------------")
// 33、查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩:
score.groupBy(_._1).mapValues(x=>(x.map(y=>y._3).sum*1.0/x.map(y=>y._3).length).formatted("%.2f").distinct).toArray.map(x=>{
student.collect({
case i if i._1==x._1=>(x._1,i._2,x._2)
})
}).flatten.filter(_._3.toDouble>=85).foreach(println(_))
println("---第34题-----------------")
// 34、查询课程名称为"数学",且分数低于 60 的学生姓名和分数:
score.map(x=>{
course.collect({
case i if i._1==x._2 =>(x._1,x._2,i._2,x._3)
})
}).flatten.map(x=>{
student.collect({
case i if i._1==x._1 => (x._1,i._2,x._2,x._3,x._4)
})
}).flatten.filter(x=>x._4.equals("数学")&&x._5<60).map(x=>(x._2,x._5)).foreach(println(_))
println("---第35题-----------------")
// 35、查询所有学生的课程及分数情况:
score.map(x=>{
course.collect({
case i if i._1==x._2 =>(x._1,x._2,i._2,x._3)
})
}).flatten.map(x=>{
student.collect({
case i if i._1==x._1 => (x._1,i._2,x._2,x._3,x._4)
})
}).flatten.foreach(println(_))
println("---第36题-----------------")
// 36、查询任何一门课程成绩在 70 分以上的学生姓名、课程名称和分数:
score.map(x=>{
course.collect({
case i if i._1==x._2 =>(x._1,x._2,i._2,x._3)
})
}).flatten.map(x=>{
student.collect({
case i if i._1==x._1 => (x._1,i._2,x._2,x._3,x._4)
})
}).flatten.filter(_._5>=70).foreach(println(_))
println("---第37题-----------------")
// 37、查询课程不及格的学生:
score.map(x=>{
course.collect({
case i if i._1==x._2 =>(x._1,x._2,i._2,x._3)
})
}).flatten.map(x=>{
student.collect({
case i if i._1==x._1 => (x._1,i._2,x._2,x._3,x._4)
})
}).flatten.filter(_._5<60).foreach(println(_))
println("---第38题-----------------")
// 38、查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名:
score.map(x=>{
course.collect({
case i if i._1==x._2 =>(x._1,x._2,i._2,x._3)
})
}).flatten.map(x=>{
student.collect({
case i if i._1==x._1 => (x._1,i._2,x._2,x._3,x._4)
})
}).flatten.filter(_._3==1).filter(_._5>=80).map(x=>(x._1,x._2)).foreach(println(_))
println("---第39题-----------------")
// 39、求每门课程的学生人数:
score.map(x=>{
course.collect({
case i if i._1==x._2 =>(x._1,x._2,i._2,x._3)
})
}).flatten.map(x=>{
student.collect({
case i if i._1==x._1 => (x._1,i._2,x._2,x._3,x._4)
})
}).flatten.groupBy(_._4).mapValues(_.length).foreach(println(_))
println("---第40题-----------------")
// 40、查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩:
score.map(x=>{
course.collect({
case i if i._1==x._2 =>(x._1,x._2,i._2,x._3)
})
}).flatten.map(x=>{
student.collect({
case i if i._1==x._1 => (x._1,i._2,x._2,x._3,x._4)
})
}).flatten.map(x=>{
teacher.collect({
case i if i._1==x._3=>(x._1,x._2,x._3,x._4,x._5,i._2)
})
}).flatten.filter(_._6=="张三").groupBy(_._5).toArray.sortWith(_._1>_._1).
head._2.map(x=>(x._1,x._2,x._5)).foreach(println(_))
println("---第41题-----------------")
// 41、查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩:
score.map(x=>{
course.collect({
case i if i._1==x._2 =>(x._1,x._2,i._2,x._3)
})
}).flatten.map(x=>{
student.collect({
case i if i._1==x._1 => (x._1,i._2,x._2,x._3,x._4)
})
}).flatten.groupBy(_._1).map(x=>x._2.groupBy(_._5).filter(_._2.length>1).foreach(x=>x._2.foreach(println(_))))
println("---第42题-----------------")
// 42、查询每门课程成绩最好的前三名:
score.map(x=>{
course.collect({
case i if i._1==x._2 =>(x._1,x._2,i._2,x._3)
})
}).flatten.map(x=>{
student.collect({
case i if i._1==x._1 => (x._1,i._2,x._2,x._3,x._4)
})
}).flatten.groupBy(_._3).map(x=>(x._2.map(y=>y).sortWith(_._5>_._5).zip(Array(1,2,3)))).foreach(_.foreach(println(_)))
println("---第43题-----------------")
// 43、统计每门课程的学生选修人数(超过 5 人的课程才统计):
// – 要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同, 按课程号升序排列
score.map(x=>{
course.collect({
case i if i._1==x._2 =>(x._1,x._2,i._2,x._3)
})
}).flatten.map(x=>{
student.collect({
case i if i._1==x._1 => (x._1,i._2,x._2,x._3,x._4)
})
}).flatten.groupBy(_._3).mapValues(_.length).toArray.filter(_._2>5).
sortWith(_._1<_._1).sortWith(_._2>_._2).foreach(println(_))
println("---第44题-----------------")
// 44、检索至少选修两门课程的学生学号:
score.map(x=>{
course.collect({
case i if i._1==x._2 =>(x._1,x._2,i._2,x._3)
})
}).flatten.map(x=>{
student.collect({
case i if i._1==x._1 => (x._1,i._2,x._2,x._3,x._4)
})
}).flatten.groupBy(_._1).mapValues(_.length).filter(_._2>=2).foreach(println(_))
println("---第45题-----------------")
// 45、查询选修了全部课程的学生信息:
score.map(x=>{
course.collect({
case i if i._1==x._2 =>(x._1,x._2,i._2,x._3)
})
}).flatten.map(x=>{
student.collect({
case i if i._1==x._1 => (x._1,i._2,x._2,x._3,x._4)
})
}).flatten.groupBy(_._2).mapValues(_.length).filter(_._2==course.length).foreach(println(_))