有没有一种方法可以与表格的某些行进行比较?

时间:2020-10-21 08:32:40

标签: sql postgresql subquery left-join

这些是我的问题的相关表格

<samlp:LogoutRequest ...

为了找到学生(enrolls.matric)可以使用的所有模块(prereqs.code),我使用了以下查询

modules
+--------+
|  code  |
+--------+
| CS1010 |
| CS2030 |
| CS2040 |
| IS3103 |
| IS2101 |
| CS3102 |
+--------+

prereqs
+--------+--------+
| code   | need   |
+--------+--------+
| CS2030 | CS1010 |
| CS2040 | CS1010 |
| IS3103 | IS2101 |
| CS3102 | CS2030 |
| CS3102 | CS2040 |
+--------+--------+

enrolls
+-----------+--------+
|  matric   | code   |
+-----------+--------+
| A0000001A | CS1010 |
| A0000001A | CS2030 |
+-----------+--------+

第二个子查询(在UNION之后)处理所有没有先决条件的模块,而第三个子查询(在EXCEPT之后)删除学生已经使用的所有模块(A0000001A)。

运行此查询时,CS3102会显示为可供学生采用的模块,但事实并非如此,因为他仅参加了CS2030,而没有参加CS2040。为了能够参加CS3102,学生需要同时参加两者 CS2030和CS2040。我不确定如何使用SQL强制执行此约束。我必须使用PostgreSQL。

当前,我的查询似乎显示只要满足其中的一个条件,就可以使用该模块。我不确定如何修改查询以确保仅在满足 all 的先决条件的情况下显示模块。

当前输出:

SELECT P.code
FROM enrolls E, prereqs P
WHERE E.matric = 'A0000001A'
  AND P.need IN (SELECT code FROM enrolls)

UNION
    
SELECT M.code
FROM modules M, prereqs P
WHERE M.code NOT IN (SELECT code FROM prereqs)

EXCEPT
    
SELECT code
FROM enrolls
WHERE matric = 'A0000001A';

所需的输出:

+--------+
|  code  |
+--------+
| CS2040 |
| CS3102 |
| IS2101 |
+--------+

2 个答案:

答案 0 :(得分:0)

这是使用not existsleft join s的一种方法:

select m.code
from modules m
left join prereqs pr on pr.code = m.code
left join enrolls e  on e.code = pr.need and e.matric = 'A0000001A'
where not exists (select 1 from enrolls e where e.code = m.code and e.matric = 'A0000001A')
group by m.code
having count(pr.code) = count(e.code)

not exists条件会过滤掉给定矩阵已经使用的模块。另一方面,left join带来了先决条件和相应的注册,而having子句确保它们都得到满足。

答案 1 :(得分:0)

我相信您可以进行某种双重否定来代替查询的第一部分和第二部分。像这样

SELECT P.code
FROM prereqs P
WHERE not exists (
      select 1 from prereqs p2 where p2.code=P.code and p2.code not in (
          select code from enrolls E where E.matric = 'A0000001A'
      )
)