按人员选择前4个得分,但至少需要两个位置

时间:2018-12-22 22:14:23

标签: mysql sql mysql-8.0

我有诸如

的数据
eventId locationId score athlete
8739    73          48  matt
8734    73          46  matt
8788    73          45  matt
8738    73          44  matt
8787    73          44  matt
8735    73          43  matt
8789    6           43  matt

我需要按人捕获前4个得分,但是前4个得分中至少有1个来自与其他3个得分不同的locationId

在这种情况下,我希望将其退回

eventId locationId score athlete
8739    73          48  matt
8734    73          46  matt
8788    73          45  matt
8789    6           43  matt

我尝试写出将使用GROUP BY HAVING MIN(locationId) != MAX(locationId)的查询,但是我不确定在完成ORDER BYLIMIT的同时如何实现。

我也尝试过进行自我联接,但是我不确定如何根据s.scorescore2返回最佳结果。

似乎在正确轨道上的自联接的开始

SELECT s.eventid, s.locationid, athlete, score
, s2.eventid, s2.locationid, s2.athlete, score score2
FROM singles s
  INNER JOIN singles s2 ON s.athlete = s2.athlete AND s.locationid != s2.locationid
WHERE s.athlete = 'matt'
ORDER BY score DESC;

2 个答案:

答案 0 :(得分:2)

您可以使用row_number分析函数和包含以下内容的limit的{​​{1}}子句

self-join

dbfiddle.uk demo

答案 1 :(得分:1)

所以,您真正想要的是前三名,然后是第一名,这保证了至少两个位置。

这是一个相当困难的条件,但我认为这可以解决问题:

with s as (
      select t.*,
             row_number() over (partition by athlete order by score desc) as seqnum
      from t
     ),
     s3 as (
      select s.*
      from s
      where seqnum <= 3
     )
select *
from s3
union all
(select s.*
 from s
 where ( (select count(distinct locationid) from s3) > 1 and seqnum = 4 ) or
       ( (select count(distinct locationid) from s3) = 1 and
         seqnum = (select min(seqnum)
                   from s
                   where locationid not in (select locationid from s3)
                  )
       )
);

Here是db <>小提琴。