选择...不存在不存在查询

Posted

技术标签:

【中文标题】选择...不存在不存在查询【英文标题】:select ... not exists not exists query 【发布时间】:2014-09-01 14:48:23 【问题描述】:
select r.index, sum(c.points)
from records r join exams e2 on r.index = e2.index
    join courses c on c.id_course = e2.id_course
where not exists ( select *
                    from required_courses rs
                    where rs.id_studie = r.id_studie
                        and not exists (select *
                                        from exams e
                                        where e.id_course = rs.id_course
                                            and r.index = e.index
                                            and score>5))
    and score>5
group by index;

我有这个问题。我知道它的作用,但不知道怎么做。

我有 16 个表的相对较大的数据库,但在这个查询中只使用了 4 个。 使用的表是:

    记录(学生)[索引(pr.key),name,surname,...,id_studie(1)(for.key)] 考试 [index(of students) (p.k.), id_course(p.k.),..., score(2), application_status] 课程 [id_course(p.k.), ..., 积分] REQUIRED_COURSES [id_studie (f.k.), id_course(f.k), ...]

(1) 我不知道更好的英文单词。在某些教职员工中,有信息学、数学、物理等课程。信息学是一门研究。 (2) 分数从 5 到 10。10 是最好的。至少需要 6 个才能通过。

查询: - 查找所有通过了 studie thay studie 所需考试的所有学生。打印索引和点数。

我的问题:可以用简单的话解释一下这是如何工作的吗?

我不明白不存在和不存在的部分。

对不起,我的英语不好。

【问题讨论】:

我认为 Joe Celko 的这篇文章可能会对您有所帮助:Divided We Stand: The SQL of Relational Division 真的很有帮助。非常感谢你。我不知道这叫除法。 【参考方案1】:

始终从内到外分析查询。

最里面的查询: 选择分数高于 5 的考试

中间一:

选择没有考试分数高于5分的必修课

外层:

选择没有必修课且未参加考试且分数高于 5 的学生

【讨论】:

我不能给你+1,因为我没有足够的声誉,但这就是我要求的 - 简单的解释。我不确定我是否会写它,但至少我现在明白了。【参考方案2】:

该示例是一个双重嵌套的NOT EXISTS 查询。

如果子查询返回任何行,EXISTS 子查询为TRUENOT EXISTS 子查询为FALSE

也就是说,它在NOT EXISTS 子句中有一个NOT EXISTS 子句。

更容易说嵌套的NOT EXISTS 回答了“x 对所有 y 都为真吗?”的问题

--Part 3
SELECT r.index, 
       SUM(c.points) 
FROM   records r 
       join exams e2 
         ON r.index = e2.index 
       join courses c 
         ON c.id_course = e2.id_course 
WHERE  NOT EXISTS (
--Part 2 starts
                   SELECT * 
                   FROM   required_courses rs 
                   WHERE  rs.id_studie = r.id_studie 
                          AND NOT EXISTS (
--Part 1 starts                                         
                                          SELECT * 
                                          FROM   exams e 
                                          WHERE  e.id_course = rs.id_course 
                                                 AND r.index = e.index 
                                                 AND score > 5
--Part 1 ends
                                                              )
--Part 2 ends                                         
                                                               )
       AND score > 5 
GROUP  BY index; 
--Part 3 ends                                         

第 1 部分:从考试表中获取得分超过 5 分的学生的所有记录。您应该在此处获取所有课程的所有及格分数学生

第 2 部分: 在学生 ID 上使用 REQUIRED_COURSES 加入第 1 部分结果,并获取学生未通过考试的所有必修课程(学生的分数不超过 5)。你应该有所有学生的课程名称,他们没有成功

第 3 部分: 将第 2 部分的结果与索引上的 RECORDS 表和课程 ID 上的 COURSES 表连接起来,以获取索引和积分总和。你可以看到这部分分为两部分。首先是带有两个表的普通JOIN,然后是带有第 2 部分的 NOT EXISTS。当您在第 2 部分应用 NOT EXISTS 时,您将获得所有成功的学生 ID,这将为您提供成功的条目,方法是添加最后是另一个SCORE > 5 条件。

【讨论】:

以上是关于选择...不存在不存在查询的主要内容,如果未能解决你的问题,请参考以下文章

在同一列中不存在某些 ID 的大表中选择数据。加快查询

SQL查询从某些表中不存在的子选择返回值?

Laravel Eloquent ORM - 选择所有两个关系都不存在的模型时,生成的 SQL 和查询构建器结果不匹配

如果不存在记录,如何选择 sum -or- 0?

不存在与不存在[重复]

获取对象时如何处理“匹配查询不存在”