SQL 中的对称对与 JOIN

Symmetric Pair in SQL with JOIN

我正在尝试查找存在对称对的学生的姓名。有 3 个表:

**student**
student_id (Primary Key) | smallint
student_name             | varchar(30)

**mathematics_marks**
student_id (Primary Key) | smallint
score                    | float (5,2)

**science_marks**
student_id (Primary Key) | smallint
score                    | float (5,2)

with Functions as (
select s.student_name as name, mm.score as math_score, sm.score as science_score 
from student s 
join mathematics_marks mm 
on mm.student_id = s.student_id
join science_marks sm 
on sm.student_id = s.student_id)
select t1.name
from Functions t1
join Functions t2
    on  t1.math_score = t2.science_score
    and t1.science_score = t2.math_score
where t1.math_score < t1.science_score

根据您的评论进行编辑:如果某学生在科学上获得的分数与其他学生在数学上获得的分数相等,并且在数学上获得的分数是与其他学生在科学方面获得的分数相同。

这就是我为这个需求编写代码的方式:

with cte as (
  select m.student_id, m.score as math_score, s.score as science_score 
  from mathematics_marks m inner join science_marks s
  on s.student_id = m.student_id 
)
select s1.student_name, s2.student_name
from cte c1 inner join cte cte2 
on c2.student_id > c1.student_id and c2.math_score = c1.science_score and c1.math_score = c2.science_score
inner join student s1 on s1.student_id = c1.student_id
inner join student s2 on s2.student_id = c2.student_id

试试这个

    select s.student_name as name, mm.score as math_score, sm.score as science_score 
    from student s 
    join mathematics_marks 
    mm 
    on mm.student_id 
    <s.student_id
       join science_marks sm 
        on sm.student_id     <s.student_id and 
    mm.math_score 
    =sm.science_score

鉴于数据结构,我假设学生在每个科目中可能有多个分数。否则,为什么将值存储在单独的表中?

为了解决这个问题,我会预先聚合标记:

with mm as (
      select student_id, group_concat(score order by score desc) as math_scores
      from mathematics_marks
      group by student_id
     ),
     sm as (
      select student_id, group_concat(score order by score desc) as science_scores
      from science_marks
      group by student_id
     ),
     sms as (
      select *
      from mm join
           sm
           using (student_id)
     )
select sms.student_id, sms2.student_id
from sms join
     sms sms2
     on sms.math_scores = sms2.science_scores and
        sms.science_scores = sms2.math_scores and
        sms.student_id < sms2.student_id;

这 returns 匹配的 ID。如果要引入名称,则需要额外加入。

注意:您已将值存储为 floats。这是相当危险的。您应该将值存储为 decimal/numeric。看起来相同的两个值实际上可能不同。