002 sql语句

完成sql语句

学生Student(stu_id,stu_name,stu_age,stu_dept)

课程Course(course_id,course_name,course_teacher_name),

选课Score(stu_id,course_id,grade)

其中stu_id代表学号,stu_name代表学生姓名,stu_age代表学生年龄,stu_dept代表学生所在系,course_id代表课程号,course_name代表课程名,course_teacher_name代表任课老师姓名,grade代表成绩 
  • 请用SQL语句建立上面三张表,注意加上约束
  • 将下列学生信息插入学生关系中:李丹,18岁,电信系,学号:20070206
  • 找出选修了课程为“112002”的学生学号和姓名(2)
  • 修改学号为“20070206”的学生所在的系为计算机(2)
  • 查询选修了数据库系统原理这门课的学生的姓名和成绩(2)
  • 统计出各门功课的最高分,显示课程编号,课程名称,与最高分 (2)
  • 查询每门课程学生选课的人数,没有被选到的课程也要统计出来
  • 查询出选课超过3门的学生信息

创建表


CREATE TABLE Student (  
    stu_id INT PRIMARY KEY,  
    stu_name VARCHAR(255) NOT NULL,  
    stu_age INT NOT NULL,  
    stu_dept VARCHAR(255) NOT NULL  
);  
  
CREATE TABLE Course (  
    course_id INT PRIMARY KEY,  
    course_name VARCHAR(255) NOT NULL,  
    course_teacher_name VARCHAR(255) NOT NULL  
);  
  
CREATE TABLE Score (  
    stu_id INT,  
    course_id INT,  
    grade FLOAT,  
    PRIMARY KEY (stu_id, course_id),  
    FOREIGN KEY (stu_id) REFERENCES Student(stu_id),  
    FOREIGN KEY (course_id) REFERENCES Course(course_id)  
);

插入学生信息

INSERT INTO Student (stu_id, stu_name, stu_age, stu_dept) VALUES (20070206, '李丹', 18, '电信系');

找出选修课程为“112002”的学生学号和姓名

SELECT s.stu_id, s.stu_name   
FROM Student s   
JOIN Score sc ON s.stu_id = sc.stu_id   
WHERE sc.course_id = 112002;

修改学号为“20070206”的学生所在的系为计算机

UPDATE Student   
SET stu_dept = '计算机'   
WHERE stu_id = 20070206;

查询选修了数据库系统原理这门课的学生的姓名和成绩

SELECT s.stu_name, sc.grade   
FROM Student s   
JOIN Score sc ON s.stu_id = sc.stu_id   
JOIN Course c ON sc.course_id = c.course_id   
WHERE c.course_name = '数据库系统原理';

统计出各门功课的最高分,显示课程编号,课程名称,与最高分

SELECT c.course_id, c.course_name, MAX(s.grade) AS max_grade  
FROM Course c  
JOIN Score s ON c.course_id = s.course_id  
GROUP BY c.course_id, c.course_name;


SELECT   
    c.course_id,   
    c.course_name,   
    (SELECT MAX(grade) FROM Score s WHERE s.course_id = c.course_id) AS max_grade  
FROM   
    Course c;



-- 这个查询的工作原理如下:

-- FROM Course c - 从Course表中选择所有的课程。
-- 对于Course表中的每一行(即每一门课程),执行子查询:
-- sql
-- (SELECT MAX(grade) FROM Score s WHERE s.course_id = c.course_id)
-- 这个子查询从Score表中找出当前课程(由外层查询的c.course_id指定)的最高成绩。

-- 最终,查询返回每门课程的编号(course_id)、名称(course_name)以及对应的最高成绩(max_grade)。
-- 这种方法允许在不使用GROUP BY子句的情况下,获取每门课程的最高分。请注意,虽然这种方法通常很有效,但如果Course表中的课程数量非常多,或者Score表中的记录非常多,这个查询的性能可能会受到影响,因为需要对Course表中的每一行执行一次子查询。在实际应用中,根据数据量和数据库的具体实现,使用GROUP BY可能会更高效。

所有课程中分数最高的那一门课及对应的分数

-- 这个语句会返回分数最高的课程ID、课程名和分数。注意,如果有多个课程有相同的最高分,这个查询只会返回其中一个

SELECT c.course_id, c.course_name, sc.grade   
FROM Score sc   
JOIN Course c ON sc.course_id = c.course_id   
WHERE sc.grade = (SELECT MAX(grade) FROM Score)   
LIMIT 1;


SELECT e.course_id, c.course_name, e.grade   
FROM Course c   
LEFT JOIN Score e ON e.course_id = c.course_id   
ORDER BY e.grade DESC   
LIMIT 1;

-- 这条语句会返回分数最高的课程和对应的分数,但请注意,由于使用了LEFT JOIN,即使某门课程没有分数(即Score表中没有对应记录),它也会出现在结果集中,但其分数会显示为NULL。在上面的ORDER BY e.grade DESC排序中,NULL值会被视为最低值。如果只关心有分数的课程,应该使用INNER JOIN代替LEFT JOIN。

查询每门课程学生选课的人数,没有被选到的课程也要统计出来


SELECT c.course_id, c.course_name, COUNT(sc.stu_id) AS student_count   
FROM Course c   
LEFT JOIN Score sc ON c.course_id = sc.course_id   
GROUP BY c.course_id, c.course_name;

查询选课超过3门的学生信息


SELECT s.*   
FROM Student s   
WHERE (SELECT COUNT(*) FROM Score sc WHERE sc.stu_id = s.stu_id) > 3;

-- 在这个查询中,我们首先通过JOIN将Student表和Score表连接起来,连接条件是学生的ID(stu_id)。然后,我们按照学生的ID以及其他需要选择的学生信息进行分组(GROUP BY)。HAVING子句用于在分组后过滤结果,只保留那些选课数(即Score表中与该学生相关的course_id的数量)超过3的学生。

-- 请注意,GROUP BY子句中包含了所有SELECT子句中提到的Student表的列,这是因为在使用GROUP BY时,SELECT子句中的非聚合列必须出现在GROUP BY子句中,这是SQL的标准要求。

SELECT s.*  
FROM Student s  
JOIN Score sc ON s.stu_id = sc.stu_id  
GROUP BY s.stu_id, s.stu_name, s.stu_age, s.stu_dept  
HAVING COUNT(sc.course_id) > 3;

-- 在这个查询中,我们使用了窗口函数COUNT(course_id) OVER (PARTITION BY stu_id)来计算每个学生的选课数,并将其作为一个子查询。然后,我们将这个子查询与Student表进行连接,并在外部查询中使用WHERE子句来过滤出选课数超过3的学生。这种方法通常比使用GROUP BY和HAVING更高效,因为它避免了分组操作。
SELECT DISTINCT s.*  
FROM Student s  
JOIN (  
    SELECT stu_id, COUNT(course_id) OVER (PARTITION BY stu_id) AS course_count  
    FROM Score  
) sc ON s.stu_id = sc.stu_id  
WHERE sc.course_count > 3;

EXISTS


SELECT product_name,sale_price
FROM PRODUCT AS P
WHERE EXISTS (SELECT * FROM SHOPPRODUCT AS SP
WHERE SP.shop_id =00C’ AND SP.product_id = P.product_id);
其中PRODUCT表示商品表,SHOPPRODUCT指商店在售商品表,其中shop_id字段表示商店id,product_id表示产品id。
以上这段sql主要是完成了哪个操作?

这段SQL查询主要完成了从PRODUCT表中检索商品名称(product_name)和销售价格(sale_price)的操作,但它并不是简单地检索所有商品,而是有一个筛选条件:只检索在SHOPPRODUCT表中有对应shop_id为‘00C’的记录的商品。

EXISTS后面带的是一个子查询,这个子查询用于检查是否存在满足特定条件的记录。具体来说,这个子查询从SHOPPRODUCT表中查找shop_id为‘00C’且product_id与外层查询中的PRODUCT表的product_id相匹配的记录。

如果EXISTS后面的子查询至少返回一条记录,这意味着外层查询中的当前PRODUCT记录有一个或多个在SHOPPRODUCT表中与shop_id为‘00C’相关联的记录。只有当这个条件满足时,外层查询才会选择该PRODUCT记录。

这里的筛选逻辑是:

对于PRODUCT表中的每一条记录,都会执行一次子查询。
子查询检查SHOPPRODUCT表中是否存在与当前PRODUCT记录的product_id相匹配,并且shop_id为‘00C’的记录。
如果存在这样的记录,那么EXISTS条件为真,外层查询就会选择这条PRODUCT记录。
如果不存在这样的记录,EXISTS条件为假,这条PRODUCT记录就不会被选择。
因此,虽然EXISTS后面的子查询本身可能返回多条记录,但外层查询并不是简单地选择所有PRODUCT表中的记录。相反,它只选择那些在SHOPPRODUCT表中有对应shop_id为‘00C’的记录的商品。

总结来说,这段SQL查询的筛选逻辑是通过EXISTS子句和子查询来实现的,它确保了只有那些在指定商店(shop_id为‘00C’)中出售的商品才会被检索出来。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简 洁 冬冬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值