背景故事
我有一个MYSQL表存储每年比赛的应用程序数据。除此之外,该表还包含Racer的ID和该竞赛申请的年份。
今年,我们希望对应用程序的随机选择过程进行加权,以便申请X连续年数的人有更大的机会被选中。
在我的PHP脚本中,我让MYSQL对象每年都会返回1条记录,随机选择一条并从DB结果数组中取消分配,将其分配给获胜者数组,并忽略所有其他获胜者今年的ID相同。
实际问题
这种方法的问题是我当前的MYSQL查询返回所有申请今年和过去比赛的人的所有记录。有没有办法(最好是使用MYSQL)我可以让它从2014年开始只返回连续的应用程序?
此SQL FIddle的示例结果集将为“1,1,1,2,2,2,2,3”。
我目前的查询是:
SELECT a.racer_id FROM applications a
WHERE a.racer_id IN
(
SELECT ab.racer_id FROM applications ab
WHERE ab.racer_id = a.racer_id AND ab.race_year=2014
)
ORDER BY RAND();
这不起作用,因为它抓住了过去几年,而不仅仅是2014年及之前的连续记录。
答案 0 :(得分:0)
另一种表达这个问题的方法是找到赛车不参赛的最近一年。然后,当年减去那一年提供连续年数。
您可以通过在年份和参赛者之间进行交叉连接来获得最近一年,并且左侧加入应用程序。没有比赛的地方是赛车手没有比赛的一年。
你必须做一些额外的簿记来处理所有年份参赛的选手。最后的查询是:
select racers.racer_id,
maxyear - max(case when a.race_year is null then years.race_year
else const.minyear - 1
end)
from (select distinct race_year
from applications
) years cross join
(select distinct racer_id
from applications
) racers cross join
(select max(race_year) as maxyear, min(race_year) as minyear
from applications
) const left outer join
applications a
on a.race_year = years.race_year and
a.racer_id = racers.racer_id
group by racers.racer_id;
我不确定这与SQL Fiddle中的数据有什么关系。你有四个赛车手,但你在问题中有8个建议值。
编辑:
现在我明白了。这很合理。以下查询基本上扩展了上述想法,加入回application
以获得最长年份之后的任何年份,无需申请。子查询是从上面简化的:
select a.racer_id
from (select racers.racer_id,
max(case when a.race_year is null then years.race_year
end) as maxyear
from (select distinct race_year
from applications
) years cross join
(select distinct racer_id
from applications
) racers left outer join
applications a
on a.race_year = years.race_year and
a.racer_id = racers.racer_id
group by racers.racer_id
) ry join
applications a
on a.racer_id = ry.racer_id and
(a.race_year > ry.maxyear or ry.maxyear is null);