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。如果要引入名称,则需要额外加入。
注意:您已将值存储为 float
s。这是相当危险的。您应该将值存储为 decimal
/numeric
。看起来相同的两个值实际上可能不同。
我正在尝试查找存在对称对的学生的姓名。有 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。如果要引入名称,则需要额外加入。
注意:您已将值存储为 float
s。这是相当危险的。您应该将值存储为 decimal
/numeric
。看起来相同的两个值实际上可能不同。