leecode更新
This commit is contained in:
parent
702985ce48
commit
254893fc23
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-04-10 12:49
|
||||||
|
*@Description:
|
||||||
|
* TODO 力扣494 目标和:
|
||||||
|
* 给你一个整数数组 nums 和一个整数 target 。
|
||||||
|
* 向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 :
|
||||||
|
* 例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。
|
||||||
|
* 返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T94_FindTargetSumWays {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
|
||||||
|
int[] nums = {1, 1, 1, 1, 1};
|
||||||
|
int target = 3;
|
||||||
|
System.out.println(findTargetSumWays(nums, target));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 思路:本质上就是一个背包问题:
|
||||||
|
* add-(sum-add)=target
|
||||||
|
* add=(sum+target)/2
|
||||||
|
* 速度击败94.6% 内存击败50.13% 2ms
|
||||||
|
* @param nums
|
||||||
|
* @param target
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int findTargetSumWays(int[] nums, int target) {
|
||||||
|
|
||||||
|
int sum = 0;
|
||||||
|
for (int num : nums) {
|
||||||
|
sum += num;
|
||||||
|
}
|
||||||
|
if ((sum + target) % 2 != 0) return 0;
|
||||||
|
int mid = (sum + target) / 2;
|
||||||
|
if (mid < 0) return 0;
|
||||||
|
int[] dp = new int[mid + 1];
|
||||||
|
dp[0] = 1;
|
||||||
|
|
||||||
|
for (int i = 0; i < nums.length; i++) {
|
||||||
|
for (int j = mid; j >= nums[i]; j--) {
|
||||||
|
dp[j] += dp[j - nums[i]];//用这个数,不用这个数
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dp[mid];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import com.markilue.leecode.tree.TreeNode;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-04-10 13:02
|
||||||
|
*@Description:
|
||||||
|
* TODO 力扣538 把二叉搜索树转换为累加树:
|
||||||
|
* 给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。
|
||||||
|
* 提醒一下,二叉搜索树满足下列约束条件:
|
||||||
|
* 节点的左子树仅包含键 小于 节点键的节点。
|
||||||
|
* 节点的右子树仅包含键 大于 节点键的节点。
|
||||||
|
* 左右子树也必须是二叉搜索树。
|
||||||
|
*@Version: 1.0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class T95_ConvertBST {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int sum = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后续遍历:递归法
|
||||||
|
* 速度击败100% 内存击败85.25% 0ms
|
||||||
|
*/
|
||||||
|
|
||||||
|
public TreeNode convertBST(TreeNode root) {
|
||||||
|
if (root == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
convertBST(root.right);
|
||||||
|
sum += root.val;
|
||||||
|
root.val = sum;
|
||||||
|
convertBST(root.left);
|
||||||
|
return root;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import com.markilue.leecode.tree.TreeNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-04-10 13:17
|
||||||
|
*@Description:
|
||||||
|
* TODO 力扣543 二叉树的直径:
|
||||||
|
* 给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T96_DiameterOfBinaryTree {
|
||||||
|
|
||||||
|
|
||||||
|
int max = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 思路:就是计算最多一条链路上的节点数目
|
||||||
|
* 速度击败100% 内存击败79.29% 递归法
|
||||||
|
* @param root
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int diameterOfBinaryTree(TreeNode root) {
|
||||||
|
sub(root);
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int sub(TreeNode root) {
|
||||||
|
if (root == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int left = sub(root.left);
|
||||||
|
int right = sub(root.right);
|
||||||
|
max = Math.max(max, left + right);
|
||||||
|
return Math.max(left, right) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,116 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-04-10 13:28
|
||||||
|
*@Description:
|
||||||
|
* TODO 力扣560 合为k的子数组:
|
||||||
|
* 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的连续子数组的个数 。
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T97_SubarraySum {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int[] nums = {100,1,2,3,100,1,2,3,4};
|
||||||
|
System.out.println(subarraySum1(nums, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 思路:滑动窗口法(维护一个窗口内总和为k的窗口)
|
||||||
|
* 有问题:因为数组里面有负数的情况,这个判断就是有问题的
|
||||||
|
* @param nums
|
||||||
|
* @param k
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int subarraySum(int[] nums, int k) {
|
||||||
|
if (nums.length == 1 && nums[0] == k) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
int cur = nums[0];
|
||||||
|
int left = 0;
|
||||||
|
int right = 1;
|
||||||
|
|
||||||
|
while (left <= right && right <= nums.length) {
|
||||||
|
if (cur == k && left != right) {
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
if (left == nums.length) break;
|
||||||
|
if (right < nums.length) {
|
||||||
|
cur += nums[right++];
|
||||||
|
} else {
|
||||||
|
cur -= nums[left++];//到终点了,直接缩小窗口
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
while (left < right && cur > k) {
|
||||||
|
|
||||||
|
cur -= nums[left++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 官方前缀和+hash优化:
|
||||||
|
* 时间复杂度O(n)
|
||||||
|
* 速度击败53.66% 内存击败29.86% 24ms
|
||||||
|
* @param nums
|
||||||
|
* @param k
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int subarraySum1(int[] nums, int k) {
|
||||||
|
int count = 0, pre = 0;
|
||||||
|
HashMap<Integer, Integer> mp = new HashMap<>();//<pre,count>
|
||||||
|
mp.put(0, 1);
|
||||||
|
for (int i = 0; i < nums.length; i++) {
|
||||||
|
pre += nums[i];
|
||||||
|
if (mp.containsKey(pre - k)) {
|
||||||
|
count += mp.get(pre - k);
|
||||||
|
}
|
||||||
|
mp.put(pre, mp.getOrDefault(pre, 0) + 1);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 官方最快:
|
||||||
|
* 速度击败92.3% 内存击败40.6% 21ms
|
||||||
|
* @param nums
|
||||||
|
* @param k
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int subarraySum2(int[] nums, int k) {
|
||||||
|
HashMap<Integer,Integer> map = new HashMap<>();
|
||||||
|
map.put(0,1);
|
||||||
|
int res = 0;
|
||||||
|
int sum = 0;
|
||||||
|
for(int i = 0;i < nums.length; i++){
|
||||||
|
sum+=nums[i];
|
||||||
|
if(map.containsKey(sum - k)){
|
||||||
|
res+=map.get(sum - k);
|
||||||
|
|
||||||
|
}
|
||||||
|
if(map.containsKey(sum)){
|
||||||
|
map.put(sum,map.get(sum)+1);
|
||||||
|
}else{
|
||||||
|
map.put(sum, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,719 @@
|
||||||
|
use sqlpractice;
|
||||||
|
|
||||||
|
# 学生表Student
|
||||||
|
create table Student
|
||||||
|
(
|
||||||
|
SId varchar(10),
|
||||||
|
Sname varchar(10),
|
||||||
|
Sage datetime,
|
||||||
|
Ssex varchar(10)
|
||||||
|
);
|
||||||
|
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 ('09', '张三', '2017-12-20', '女');
|
||||||
|
insert into Student
|
||||||
|
values ('10', '李四', '2017-12-25', '女');
|
||||||
|
insert into Student
|
||||||
|
values ('11', '李四', '2017-12-30', '女');
|
||||||
|
insert into Student
|
||||||
|
values ('12', '赵六', '2017-01-01', '女');
|
||||||
|
insert into Student
|
||||||
|
values ('13', '孙七', '2018-01-01', '女');
|
||||||
|
|
||||||
|
# 科目表
|
||||||
|
create table Course
|
||||||
|
(
|
||||||
|
CId varchar(10),
|
||||||
|
Cname nvarchar(10),
|
||||||
|
TId varchar(10)
|
||||||
|
);
|
||||||
|
insert into Course
|
||||||
|
values ('01', '语文', '02');
|
||||||
|
insert into Course
|
||||||
|
values ('02', '数学', '01');
|
||||||
|
insert into Course
|
||||||
|
values ('03', '英语', '03');
|
||||||
|
|
||||||
|
# 教师表
|
||||||
|
create table Teacher
|
||||||
|
(
|
||||||
|
TId varchar(10),
|
||||||
|
Tname varchar(10)
|
||||||
|
);
|
||||||
|
insert into Teacher
|
||||||
|
values ('01', '张三');
|
||||||
|
insert into Teacher
|
||||||
|
values ('02', '李四');
|
||||||
|
insert into Teacher
|
||||||
|
values ('03', '王五');
|
||||||
|
|
||||||
|
# 成绩表SC
|
||||||
|
create table SC
|
||||||
|
(
|
||||||
|
SId varchar(10),
|
||||||
|
CId varchar(10),
|
||||||
|
score decimal(18, 1)
|
||||||
|
);
|
||||||
|
insert into SC
|
||||||
|
values ('01', '01', 80);
|
||||||
|
insert into SC
|
||||||
|
values ('01', '02', 90);
|
||||||
|
insert into SC
|
||||||
|
values ('01', '03', 99);
|
||||||
|
insert into SC
|
||||||
|
values ('02', '01', 70);
|
||||||
|
insert into SC
|
||||||
|
values ('02', '02', 60);
|
||||||
|
insert into SC
|
||||||
|
values ('02', '03', 80);
|
||||||
|
insert into SC
|
||||||
|
values ('03', '01', 80);
|
||||||
|
insert into SC
|
||||||
|
values ('03', '02', 80);
|
||||||
|
insert into SC
|
||||||
|
values ('03', '03', 80);
|
||||||
|
insert into SC
|
||||||
|
values ('04', '01', 50);
|
||||||
|
insert into SC
|
||||||
|
values ('04', '02', 30);
|
||||||
|
insert into SC
|
||||||
|
values ('04', '03', 20);
|
||||||
|
insert into SC
|
||||||
|
values ('05', '01', 76);
|
||||||
|
insert into SC
|
||||||
|
values ('05', '02', 87);
|
||||||
|
insert into SC
|
||||||
|
values ('06', '01', 31);
|
||||||
|
insert into SC
|
||||||
|
values ('06', '03', 34);
|
||||||
|
insert into SC
|
||||||
|
values ('07', '02', 89);
|
||||||
|
insert into SC
|
||||||
|
values ('07', '03', 98);
|
||||||
|
|
||||||
|
|
||||||
|
#TODO 1、查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数
|
||||||
|
|
||||||
|
select Student.sid, sname, sage, Ssex, s1, s2
|
||||||
|
from student
|
||||||
|
join
|
||||||
|
(select t1.SId, s1, s2
|
||||||
|
from (select SId, score s1
|
||||||
|
from sc
|
||||||
|
where CId = '01') t1
|
||||||
|
join
|
||||||
|
(select SId, score s2
|
||||||
|
from sc
|
||||||
|
where CId = '02') t2 on t1.SId = t2.SId and t1.s1 > t2.s2) t3 on Student.SId = t3.SId;
|
||||||
|
|
||||||
|
#TODO 2.1、查询同时存在" 01 "课程和" 02 "课程的情况
|
||||||
|
select t1.SId, s1, s2
|
||||||
|
from (select SId, score s1
|
||||||
|
from sc
|
||||||
|
where CId = '01') t1
|
||||||
|
join
|
||||||
|
(select SId, score s2
|
||||||
|
from sc
|
||||||
|
where CId = '02') t2 on t1.SId = t2.SId;
|
||||||
|
|
||||||
|
#TODO 2.2、查询存在" 01 "课程但可能不存在" 02 "课程的情况(不存在时显示为 null )
|
||||||
|
select t1.sid, s1, s2
|
||||||
|
from (select SId, score s1
|
||||||
|
from sc
|
||||||
|
where CId = '01') t1
|
||||||
|
left join (select SId, score s2
|
||||||
|
from sc
|
||||||
|
where CId = '02') t2 on t1.SId = t2.SId;
|
||||||
|
|
||||||
|
|
||||||
|
#TODO 2.3、查询不存在" 01 "课程但存在" 02 "课程的情况
|
||||||
|
select t2.sid, s1, s2
|
||||||
|
from (select SId, score s1
|
||||||
|
from sc
|
||||||
|
where CId = '01') t1
|
||||||
|
right join (select SId, score s2
|
||||||
|
from sc
|
||||||
|
where CId = '02') t2 on t1.SId = t2.SId;
|
||||||
|
|
||||||
|
#TODO 3、查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩
|
||||||
|
-- 查询平均成绩大于等于 60 分的同学
|
||||||
|
select SId, sum(score) / count(score) avg
|
||||||
|
from sc
|
||||||
|
group by sid
|
||||||
|
having avg > 60;
|
||||||
|
|
||||||
|
-- 查询这些学生的相关信息
|
||||||
|
select t1.sid, Sname, avg
|
||||||
|
from student
|
||||||
|
right join (select SId, sum(score) / count(score) avg
|
||||||
|
from sc
|
||||||
|
group by sid
|
||||||
|
having avg > 60) t1 on Student.SId = t1.SId;
|
||||||
|
|
||||||
|
#TODO 4、查询在 SC 表存在成绩的学生信息
|
||||||
|
-- 存在成绩+去重
|
||||||
|
select sid
|
||||||
|
from sc
|
||||||
|
where score is not null
|
||||||
|
group by sid;
|
||||||
|
-- 查询对应的信息
|
||||||
|
select t1.sid, Sname, Sage, Ssex
|
||||||
|
from student
|
||||||
|
right join (select sid
|
||||||
|
from sc
|
||||||
|
where score is not null
|
||||||
|
group by sid) t1 on Student.SId = t1.SId;
|
||||||
|
|
||||||
|
#TODO 5、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )
|
||||||
|
-- 查询有成绩的
|
||||||
|
select sid, count(score) c1, sum(score) s1
|
||||||
|
from sc
|
||||||
|
group by sid;
|
||||||
|
|
||||||
|
select Student.sid, sname, c1, s1
|
||||||
|
from student
|
||||||
|
left join(select sid, count(score) c1, sum(score) s1
|
||||||
|
from sc
|
||||||
|
group by sid) t1 on Student.sid = t1.SId;
|
||||||
|
|
||||||
|
#TODO 6、查有成绩的学生信息
|
||||||
|
-- 有成绩的学生
|
||||||
|
select distinct(sid)
|
||||||
|
from sc
|
||||||
|
where score is not null;
|
||||||
|
-- 查询对应的信息
|
||||||
|
select Student.sid, Student.sname, Student.sage, ssex
|
||||||
|
from student
|
||||||
|
right join (select distinct(sid) sid
|
||||||
|
from sc
|
||||||
|
where score is not null) t1 on Student.SId = t1.SId;
|
||||||
|
|
||||||
|
#TODO 7、查询「李」姓老师的数量
|
||||||
|
select count(TId)
|
||||||
|
from Teacher
|
||||||
|
where Tname like '李%';
|
||||||
|
|
||||||
|
#TODO 8、查询学过「张三」老师授课的同学的信息
|
||||||
|
|
||||||
|
-- 张三老师教过的课
|
||||||
|
select cid, t.TId
|
||||||
|
from Course
|
||||||
|
join
|
||||||
|
(select tid, tname from teacher where tname = '张三') t on Course.TId = t.TId;
|
||||||
|
|
||||||
|
-- 张三老师教过的课的学生
|
||||||
|
select sid, t2.CId
|
||||||
|
from sc
|
||||||
|
join (select cid, t.TId
|
||||||
|
from Course
|
||||||
|
join
|
||||||
|
(select tid, tname from teacher where tname = '张三') t on Course.TId = t.TId) t2
|
||||||
|
on sc.CId = t2.CId;
|
||||||
|
|
||||||
|
-- 详细信息
|
||||||
|
select t3.sid, Sname, sage, Ssex
|
||||||
|
from student
|
||||||
|
join(select sid, t2.CId
|
||||||
|
from sc
|
||||||
|
join (select cid, t.TId
|
||||||
|
from Course
|
||||||
|
join
|
||||||
|
(select tid, tname from teacher where tname = '张三') t on Course.TId = t.TId) t2
|
||||||
|
on sc.CId = t2.CId) t3 on Student.SId = t3.SId;
|
||||||
|
|
||||||
|
#TODO 9、查询没有学全所有课程的同学的信息
|
||||||
|
|
||||||
|
-- 查询全部course的数目
|
||||||
|
select count(cid) num
|
||||||
|
from course;
|
||||||
|
|
||||||
|
-- 查询没有学全所有课程的同学
|
||||||
|
select sid, count(cid) c1, num
|
||||||
|
from sc,
|
||||||
|
(select count(cid) num
|
||||||
|
from course) t2
|
||||||
|
group by sid
|
||||||
|
having c1 < t2.num;
|
||||||
|
|
||||||
|
-- 查询对应学生的信息
|
||||||
|
select S.sid, sname, Sage, Ssex
|
||||||
|
from Student
|
||||||
|
right join (select sid, count(cid) c1, num
|
||||||
|
from sc,
|
||||||
|
(select count(cid) num
|
||||||
|
from course) t2
|
||||||
|
group by sid
|
||||||
|
having c1 < t2.num) S on Student.SId = S.SId;
|
||||||
|
|
||||||
|
#TODO 10、查询至少有一门课与学号为" 01 "的同学所学相同的同学的信息
|
||||||
|
|
||||||
|
-- 学号01同学所学
|
||||||
|
SELECT CId
|
||||||
|
from sc
|
||||||
|
where SId = '01';
|
||||||
|
|
||||||
|
-- 所学相同
|
||||||
|
select Student.sid, sname, Sage, Ssex
|
||||||
|
from Student
|
||||||
|
where SId in
|
||||||
|
(select distinct (sid)
|
||||||
|
from sc
|
||||||
|
join(SELECT CId
|
||||||
|
from sc
|
||||||
|
where SId = '01') t1 on sc.CId = t1.CId
|
||||||
|
where SC.SId != '01');
|
||||||
|
|
||||||
|
#TODO 11、查询和" 01 "号的同学学习的课程完全相同的其他同学的信息
|
||||||
|
|
||||||
|
-- 先join得到所有的相同的课
|
||||||
|
|
||||||
|
-- 计算所有课的数目和原本的数目是否相等
|
||||||
|
select sc.sid
|
||||||
|
from sc
|
||||||
|
join(select CId
|
||||||
|
from sc
|
||||||
|
where SId = '01') t1 on sc.CId = t1.CId
|
||||||
|
where sid != '01'
|
||||||
|
group by SId
|
||||||
|
having count(sc.cid) = (select count(CId)
|
||||||
|
from sc
|
||||||
|
where SId = '01');
|
||||||
|
|
||||||
|
select *
|
||||||
|
from student
|
||||||
|
where Student.SId in (select sc.sid
|
||||||
|
from sc
|
||||||
|
join(select CId
|
||||||
|
from sc
|
||||||
|
where SId = '01') t1 on sc.CId = t1.CId
|
||||||
|
where sid != '01'
|
||||||
|
group by SId
|
||||||
|
having count(sc.cid) = (select count(CId)
|
||||||
|
from sc
|
||||||
|
where SId = '01'));
|
||||||
|
|
||||||
|
#TODO 12、查询没学过"张三"老师讲授的任一门课程的学生姓名
|
||||||
|
|
||||||
|
-- 查询张三老师教过的课
|
||||||
|
select cid
|
||||||
|
from course
|
||||||
|
join(select TId
|
||||||
|
from teacher
|
||||||
|
where Tname = '张三') t1
|
||||||
|
on Course.TId = t1.TId;
|
||||||
|
-- 查询学过张三老师教过的课的学生
|
||||||
|
select SId
|
||||||
|
from sc
|
||||||
|
where CId in (select cid
|
||||||
|
from course
|
||||||
|
join(select TId
|
||||||
|
from teacher
|
||||||
|
where Tname = '张三') t1
|
||||||
|
on Course.TId = t1.TId);
|
||||||
|
-- 查询没有学过张三老师教过的课的学生
|
||||||
|
select *
|
||||||
|
from student
|
||||||
|
where SId not in (select SId
|
||||||
|
from sc
|
||||||
|
where CId in (select cid
|
||||||
|
from course
|
||||||
|
where tid in (select TId
|
||||||
|
from teacher
|
||||||
|
where Tname = '张三')));
|
||||||
|
|
||||||
|
# TODO 13、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
|
||||||
|
|
||||||
|
-- 查询两门及其以上不及格课程的同学的学号
|
||||||
|
select sid, count(CId) c1
|
||||||
|
from sc
|
||||||
|
where score < 60
|
||||||
|
group by sid
|
||||||
|
having c1 >= 2;
|
||||||
|
|
||||||
|
-- 查询这些人的平均成绩
|
||||||
|
select sid, avg(score) avg
|
||||||
|
from sc
|
||||||
|
where SId in
|
||||||
|
(select sid
|
||||||
|
from sc
|
||||||
|
where score < 60
|
||||||
|
group by sid
|
||||||
|
having count(CId) >= 2)
|
||||||
|
group by sid;
|
||||||
|
-- 查询全部
|
||||||
|
select t1.sid, Sname, avg
|
||||||
|
from student
|
||||||
|
join
|
||||||
|
(select sid, avg(score) avg
|
||||||
|
from sc
|
||||||
|
where SId in
|
||||||
|
(select sid
|
||||||
|
from sc
|
||||||
|
where score < 60
|
||||||
|
group by sid
|
||||||
|
having count(CId) >= 2)
|
||||||
|
group by sid) t1 on Student.SId = t1.SId;
|
||||||
|
|
||||||
|
#TODO 14、检索" 01 "课程分数小于 60,按分数降序排列的学生信息
|
||||||
|
-- 降序学生
|
||||||
|
select sid, score
|
||||||
|
from sc
|
||||||
|
where CId = '01'
|
||||||
|
and score < 60
|
||||||
|
order by score desc;
|
||||||
|
|
||||||
|
select *
|
||||||
|
from Student
|
||||||
|
join
|
||||||
|
(select sid, score
|
||||||
|
from sc
|
||||||
|
where CId = '01'
|
||||||
|
and score < 60
|
||||||
|
order by score desc) t1 on Student.SId = t1.SId;
|
||||||
|
|
||||||
|
#TODO 15、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
|
||||||
|
select sid, CId, score, avg
|
||||||
|
from (select sid,
|
||||||
|
CId,
|
||||||
|
score,
|
||||||
|
avg(score) over (partition by sid) avg
|
||||||
|
from sc) t1
|
||||||
|
order by avg desc;
|
||||||
|
|
||||||
|
|
||||||
|
#TODO 16、查询各科成绩最高分、最低分和平均分:
|
||||||
|
select cid, max(score), min(score), avg(score)
|
||||||
|
from sc
|
||||||
|
group by cid;
|
||||||
|
|
||||||
|
#TODO 17.1、按各科成绩进行排序,并显示排名, Score 重复时保留名次空缺
|
||||||
|
|
||||||
|
-- 窗口函数
|
||||||
|
select cid, sid, score, rank() over (partition by CId order by score desc)
|
||||||
|
from sc;
|
||||||
|
|
||||||
|
-- 师兄非窗口函数法
|
||||||
|
SELECT *, COUNT(*)
|
||||||
|
FROM sc a
|
||||||
|
LEFT JOIN
|
||||||
|
sc b
|
||||||
|
ON a.cid = b.cid AND a.score <= b.score
|
||||||
|
GROUP BY a.cid, a.sid, a.score
|
||||||
|
ORDER BY a.cid DESC, a.score DESC;
|
||||||
|
|
||||||
|
#TODO 17.2、按各科成绩进行排序,并显示排名, Score 重复时合并名次
|
||||||
|
-- 窗口函数
|
||||||
|
select cid, sid, score, dense_rank() over (partition by CId order by score desc)
|
||||||
|
from sc;
|
||||||
|
-- 师兄非窗口函数法 (应该有问题)
|
||||||
|
SELECT *, COUNT(*)
|
||||||
|
FROM sc a
|
||||||
|
LEFT JOIN
|
||||||
|
sc b
|
||||||
|
ON a.cid = b.cid AND a.score < b.score
|
||||||
|
GROUP BY a.cid, a.sid, a.score
|
||||||
|
ORDER BY a.cid DESC, a.score DESC;
|
||||||
|
|
||||||
|
|
||||||
|
# TODO 17.3、查询学生的总成绩,并进行排名,总分重复时保留名次空缺
|
||||||
|
|
||||||
|
-- 非窗口函数法
|
||||||
|
select t1.sid, t1.sum, count(*) rk
|
||||||
|
from (select sid, sum(score) sum
|
||||||
|
from sc
|
||||||
|
group by sid) t1
|
||||||
|
left join
|
||||||
|
(select sid, sum(score) sum
|
||||||
|
from sc
|
||||||
|
group by sid) t2 on t1.sum <= t2.sum
|
||||||
|
group by t1.sid, t1.sum
|
||||||
|
order by t1.sum desc;
|
||||||
|
|
||||||
|
-- 窗口函数法
|
||||||
|
select sid, sum, rank() over (order by sum desc) rk
|
||||||
|
from (select sid, sum(score) sum
|
||||||
|
from sc
|
||||||
|
group by sid) t1;
|
||||||
|
|
||||||
|
#TODO 17.4、 查询学生的总成绩,并进行排名,总分重复时不保留名次空缺
|
||||||
|
|
||||||
|
-- 窗口函数法
|
||||||
|
select sid, sum, dense_rank() over (order by sum desc) rk
|
||||||
|
from (select sid, sum(score) sum
|
||||||
|
from sc
|
||||||
|
group by sid) t1;
|
||||||
|
|
||||||
|
SET @crank = 0;
|
||||||
|
SELECT b.sid, b.a, @crank := @crank + 1 AS rank1
|
||||||
|
FROM (SELECT sid, SUM(score) AS a FROM sc GROUP BY sid ORDER BY a DESC) b;
|
||||||
|
|
||||||
|
#TODO 18.统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] 及所占百分比
|
||||||
|
|
||||||
|
select t1.cid,cname,you,liang,zhong,cha,you/total,liang/total,zhong/total,cha/total
|
||||||
|
from course
|
||||||
|
join
|
||||||
|
(
|
||||||
|
select cid,
|
||||||
|
sum(if(score >= 85 and score < 100, 1, 0)) you,
|
||||||
|
sum(if(score >= 70 and score < 85, 1, 0)) liang,
|
||||||
|
sum(if(score >= 60 and score < 70, 1, 0)) zhong,
|
||||||
|
sum(if(score > 0 and score < 60, 1, 0)) cha,
|
||||||
|
count(score) total
|
||||||
|
from sc
|
||||||
|
group by cid
|
||||||
|
)t1 on Course.CId=t1.CId;
|
||||||
|
|
||||||
|
-- 师兄写法
|
||||||
|
SELECT sc.cid,c.cname,
|
||||||
|
SUM(CASE WHEN score>85 AND score<=100 THEN 1 ELSE 0 END) AS '[100-85]',
|
||||||
|
SUM(CASE WHEN score>70 AND score<=85 THEN 1 ELSE 0 END) AS '[85-70]',
|
||||||
|
SUM(CASE WHEN score>60 AND score<=70 THEN 1 ELSE 0 END) AS '[70-60]',
|
||||||
|
SUM(CASE WHEN score<60 THEN 1 ELSE 0 END) AS '[60-0]',
|
||||||
|
SUM(CASE WHEN score>85 AND score<=100 THEN 1 ELSE 0 END)/COUNT(1) AS '[100-85]百分比',
|
||||||
|
SUM(CASE WHEN score>70 AND score<=85 THEN 1 ELSE 0 END)/COUNT(1) AS '[85-70]百分比',
|
||||||
|
SUM(CASE WHEN score>60 AND score<=70 THEN 1 ELSE 0 END)/COUNT(1) AS '[70-60]百分比',
|
||||||
|
SUM(CASE WHEN score<60 THEN 1 ELSE 0 END)/COUNT(1) AS '[60-0]百分比'
|
||||||
|
FROM sc ,course c
|
||||||
|
WHERE sc.cid=c.cid
|
||||||
|
GROUP BY sc.cid;
|
||||||
|
|
||||||
|
# TODO 19查询各科成绩前三名的记录
|
||||||
|
|
||||||
|
-- 窗口函数法
|
||||||
|
select cid,sid,score,rk
|
||||||
|
from
|
||||||
|
(
|
||||||
|
select cid,sid,score,rank() over (partition by cid order by score desc) rk
|
||||||
|
from sc
|
||||||
|
) t1
|
||||||
|
where rk<=3;
|
||||||
|
|
||||||
|
-- 师兄非窗口函数写法
|
||||||
|
SELECT cid,sid,score FROM sc a
|
||||||
|
WHERE (SELECT COUNT(1) FROM sc b WHERE a.cid=b.cid AND a.score<=b.score)<=3
|
||||||
|
ORDER BY cid;
|
||||||
|
|
||||||
|
#TODO 20.查询每门课程被选修的学生数
|
||||||
|
select Course.cid,Cname,student_num
|
||||||
|
from course
|
||||||
|
left join
|
||||||
|
(
|
||||||
|
select cid,count(sid) student_num
|
||||||
|
from sc
|
||||||
|
group by cid
|
||||||
|
) t1 on Course.CId=t1.CId;
|
||||||
|
|
||||||
|
#TODO 21 查询出只选修两门课程的学生学号和姓名
|
||||||
|
select t1.sid,Sname
|
||||||
|
from student
|
||||||
|
join
|
||||||
|
(
|
||||||
|
select sid,count(cid) num
|
||||||
|
from sc
|
||||||
|
group by sid
|
||||||
|
having num=2
|
||||||
|
) t1 on Student.SId=t1.SId;
|
||||||
|
|
||||||
|
#TODO 22.查询男生、女生人数`student`
|
||||||
|
select sum(if(Ssex='男',1,0)) '男生数量',sum(if(Ssex='女',1,0)) '女生数量'
|
||||||
|
from student;
|
||||||
|
|
||||||
|
SELECT Ssex,COUNT(*) num FROM student GROUP BY ssex;
|
||||||
|
|
||||||
|
#TODO 23.查询名字中含有「风」字的学生信息
|
||||||
|
select *
|
||||||
|
from student
|
||||||
|
where Sname like '%风%';
|
||||||
|
|
||||||
|
#TODO 24.查询同名同姓学生名单,并统计同名人数
|
||||||
|
|
||||||
|
select sname ,count(sid) num
|
||||||
|
from student
|
||||||
|
group by sname
|
||||||
|
having num>1;
|
||||||
|
|
||||||
|
#TODO 25.查询 1990 年出生的学生名单
|
||||||
|
select sid,sname,Sage
|
||||||
|
from student
|
||||||
|
where year(Sage)='1990';
|
||||||
|
|
||||||
|
SELECT * FROM student WHERE sage LIKE '1990%';
|
||||||
|
|
||||||
|
#TODO 26.查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
|
||||||
|
|
||||||
|
select cid,avg(score) avg
|
||||||
|
from sc
|
||||||
|
group by cid
|
||||||
|
order by avg desc,cid;
|
||||||
|
|
||||||
|
#TODO 27.查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩
|
||||||
|
|
||||||
|
select t1.sid,sname,avg
|
||||||
|
from student
|
||||||
|
right join
|
||||||
|
(
|
||||||
|
select sid,avg(score) avg
|
||||||
|
from sc
|
||||||
|
group by sid
|
||||||
|
having avg>=85
|
||||||
|
) t1 on Student.SId=t1.sid;
|
||||||
|
|
||||||
|
#TODO 28.查询课程名称为「数学」,且分数低于 60 的学生姓名和分数
|
||||||
|
|
||||||
|
select t1.sid,Sname,score
|
||||||
|
from student
|
||||||
|
join
|
||||||
|
(
|
||||||
|
select cid,SId,score
|
||||||
|
from sc
|
||||||
|
where cid=
|
||||||
|
(
|
||||||
|
select cid
|
||||||
|
from Course
|
||||||
|
where Cname ='数学'
|
||||||
|
)and score<60
|
||||||
|
) t1 on Student.SId=t1.SId;
|
||||||
|
|
||||||
|
#TODO 29.查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)
|
||||||
|
|
||||||
|
select Student.sid,sname,ifnull(Cname,'无'),ifnull(score,0)
|
||||||
|
from student
|
||||||
|
left join
|
||||||
|
(
|
||||||
|
select sid,sc.cid,cname,score
|
||||||
|
from sc,course
|
||||||
|
where sc.cid=Course.CId
|
||||||
|
)t1 on Student.SId=t1.SId;
|
||||||
|
|
||||||
|
#TODO 30.查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数
|
||||||
|
|
||||||
|
select sc.sid,sname,sc.cid,cname,score
|
||||||
|
from sc,course,student
|
||||||
|
where sc.CId=Course.CId and Student.SId=sc.SId and score>70;
|
||||||
|
|
||||||
|
SELECT t3.sname,t2.cname,t1.score FROM
|
||||||
|
(
|
||||||
|
(SELECT * FROM sc) t1
|
||||||
|
JOIN
|
||||||
|
(SELECT cid,cname FROM course) t2
|
||||||
|
JOIN
|
||||||
|
(SELECT sid,sname FROM student) t3
|
||||||
|
ON t1.cid=t2.cid AND t1.sid=t3.sid
|
||||||
|
)
|
||||||
|
WHERE t1.score > 70;
|
||||||
|
|
||||||
|
#TODO 31.查询不及格的课程
|
||||||
|
select sid,cid,score,(case when score<60 then 'fail' else 'success' end) result
|
||||||
|
from sc
|
||||||
|
where score<60;
|
||||||
|
|
||||||
|
# TODO 32.查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名
|
||||||
|
select sid,Sname
|
||||||
|
from Student
|
||||||
|
where sid in
|
||||||
|
(select sid
|
||||||
|
from sc
|
||||||
|
where cid='01'and score>=80);
|
||||||
|
|
||||||
|
-- 也可以join获得具体的数
|
||||||
|
SELECT student.`SId`,student.`Sname`,sc.`CId`,sc.`score`
|
||||||
|
FROM sc,student
|
||||||
|
WHERE sc.`SId`=student.`SId` AND sc.`CId`=01 AND sc.`score`>=80;
|
||||||
|
|
||||||
|
#TODO 33.求每门课程的学生人数
|
||||||
|
select cid,count(sid) num
|
||||||
|
from sc
|
||||||
|
group by cid;
|
||||||
|
|
||||||
|
#TODO 34.成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
|
||||||
|
select student.sid, sname, sage, ssex,cid, score
|
||||||
|
from student
|
||||||
|
join
|
||||||
|
(
|
||||||
|
select sid,cid,score
|
||||||
|
from sc
|
||||||
|
where CId
|
||||||
|
in (select CId
|
||||||
|
from course
|
||||||
|
where TId in(select TId from teacher where Tname='张三'))
|
||||||
|
having score=max(score)
|
||||||
|
) t1 on Student.SId=t1.SId;
|
||||||
|
|
||||||
|
SELECT t2.sid,t2.cid,MAX(t2.score) FROM
|
||||||
|
(
|
||||||
|
(SELECT CId FROM course WHERE TId = (SELECT tid FROM teacher WHERE Tname='张三'))t1
|
||||||
|
JOIN
|
||||||
|
(SELECT * FROM sc) t2
|
||||||
|
ON t1.cid=t2.cid
|
||||||
|
);
|
||||||
|
|
||||||
|
#TODO 35.成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
|
||||||
|
|
||||||
|
-- 本人的应该有没有重复都行
|
||||||
|
select student.sid, sname, sage, ssex,cid, score
|
||||||
|
from student
|
||||||
|
join
|
||||||
|
(
|
||||||
|
select sid,cid,score
|
||||||
|
from sc
|
||||||
|
where CId
|
||||||
|
in (select CId
|
||||||
|
from course
|
||||||
|
where TId in(select TId from teacher where Tname='张三'))
|
||||||
|
having score=max(score)
|
||||||
|
) t1 on Student.SId=t1.SId;
|
||||||
|
|
||||||
|
# TODO 36.查询不同课程成绩相同的学生的学生编号、课程编号、学生编号
|
||||||
|
-- 窗口函数
|
||||||
|
-- 查询不同课程成绩相同的学生的学生编号
|
||||||
|
select sid,score,CId,num
|
||||||
|
from
|
||||||
|
(
|
||||||
|
select sid,score,cid,count(cid) over(partition by sid,score) num
|
||||||
|
from sc
|
||||||
|
)t1
|
||||||
|
where num>1;
|
||||||
|
|
||||||
|
-- 师兄不用窗口函数法(有四门课及以上的应该不对)
|
||||||
|
SELECT * FROM sc a
|
||||||
|
WHERE sid IN
|
||||||
|
(SELECT sid FROM sc
|
||||||
|
GROUP BY sid
|
||||||
|
HAVING (COUNT(*)=2 AND COUNT(DISTINCT score)=1) -- 有两门课有重复的情况
|
||||||
|
OR (COUNT(*)=3 AND COUNT(DISTINCT score)<3)); -- 有三门课有重复的情况
|
||||||
|
|
||||||
|
-- 根据师兄的改进(去重前后不相等则有重复)
|
||||||
|
SELECT * FROM sc a
|
||||||
|
WHERE sid IN
|
||||||
|
(SELECT sid FROM sc
|
||||||
|
GROUP BY sid
|
||||||
|
HAVING COUNT(*) != COUNT(DISTINCT score));
|
||||||
|
|
||||||
|
#TODO 37.查询各学生的年龄,只按年份来算
|
||||||
|
|
||||||
|
SELECT sid,sname, YEAR(now())-YEAR(sage) age FROM student;
|
||||||
|
|
||||||
|
#TODO 38.按照出生日期来算,当前月日
|
||||||
|
SELECT sid,sname,TIMESTAMPDIFF(YEAR,sage,CURDATE()) age FROM student;
|
||||||
|
|
||||||
|
-- 自己的本办法
|
||||||
|
-- 判断年龄是否要-1
|
||||||
|
select sid,sname ,year(now())-year(Sage)-if(month(now())-month(Sage)>0||(month(now())=month(Sage)&&day(now())>=day(Sage)),0,1) age
|
||||||
|
from student;
|
||||||
|
|
||||||
|
#TODO 39.查询本周过生日的学生
|
||||||
|
SELECT * FROM student WHERE WEEKOFYEAR(sage)=WEEKOFYEAR(CURDATE())
|
||||||
|
|
||||||
Loading…
Reference in New Issue