【问题标题】:Symmetric Pair in SQL with JOINSQL 中的对称对与 JOIN
【发布时间】:2019-12-15 10:23:48
【问题描述】:

我正在尝试查找存在对称对的学生的姓名。有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

编辑您的评论:如果该学生在科学中获得的分数等于其他学生在数学中获得的分数并且在数学中获得的分数相同,则该学生被称为对称对的一部分作为其他科学学生获得的分数。

【问题讨论】:

  • '对称对' - 那是什么?
  • 如果一个学生的科学分数与其他学生的数学分数相等且数学分数相同,则称该学生为对称对的一部分作为其他科学学生获得的分数。
  • @ajeevanshgautam 你不接受我的回答吗?

标签: mysql sql mysql-workbench rdbms


【解决方案1】:

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

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

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;

这将返回匹配的 id。如果你想引入名字,你需要一个额外的加入。

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

【讨论】:

  • 上面代码中这个sms2是什么。没有像sms2这样定义的表
  • @ajeevanshgautam 。 . .它现在 - 正如它最初应该是 - 一个表别名。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    试试这个

        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
    

    【讨论】:

      猜你喜欢
      • 2015-10-27
      • 2020-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-19
      • 1970-01-01
      • 2010-09-29
      相关资源
      最近更新 更多