PostgreSQL LEFT OUTER JOIN 条件不起作用

PostgreSQL LEFT OUTER JOIN Conditionals not working

这个带有多个条件的 LEFT OUTER JOIN 不起作用,这可能是显而易见的。它返回所有不同 sid 的结果并且根本不执行条件。

SELECT
 count(distinct student_status.sid)
FROM studentcoursedb.student_status
      LEFT OUTER JOIN studentcoursedb.student_status AS t0
        ON t0.sid = student_status.sid
      AND t0.term < student_status.term
      AND student_status.major LIKE 'ABC%';

结果,32684 是不同 sid 的总数,与此查询返回的值相同:

select count(distinct sid)
from studentcoursedb.student_status;

二次查询

SELECT
 count(distinct student_status.sid)
FROM studentcoursedb.student_status
      LEFT OUTER JOIN studentcoursedb.student_status AS t0
        ON t0.sid = student_status.sid
      AND t0.term < student_status.term
      AND student_status.major LIKE 'ABC%';


select count(distinct sid)
from studentcoursedb.student_status;

return行数相同因为

您左连接(左连接或左外连接相同)相同table这意味着结果行数与主行数相同table

如果你想要一个子集匹配,你应该使用内部连接(或其他连接关系)

您正在从左侧计算一列 table,由于 LEFT JOIN,该列可能有重复的行,但肯定没有过滤的行。

A LEFT OUTER JOIN 保留 第一个 table 中的所有行以及第二个中的匹配行。因此,它不会过滤第一个 table。您正在从第一个 table 开始计算一列。因此,LEFT OUTER JOIN 不会影响非重复计数。

如果要过滤行,请改用 INNER JOIN。我还将条件移动到 WHERE 子句:

SELECT count(distinct ss.sid)
FROM studentcoursedb.student_status ss INNER JOIN     
     studentcoursedb.student_status ss2
     ON ss2.sid = ss.sid
WHERE ss2.term < ss.term AND ss.major LIKE 'ABC%';

请注意,我认为您不需要自行加入。您是否考虑过:

select dense_rank(ss.term) over (order by term)
from studentcoursedb.student_status ss
where ss.major like 'ABC%';

更简单,应该有更好的性能。