Php 选择最低连续值?
背景故事Php 选择最低连续值?,php,mysql,Php,Mysql,背景故事 我有一个MYSQL表,用于存储年度比赛的应用程序数据。除此之外,该表还保存了参赛者的ID和该比赛申请的年份 今年,我们希望对申请的随机选择过程进行加权,这样连续申请X年的人有更大的被选中的机会 在我的PHP脚本中,我让MYSQL对象为他们应用的每一年返回1条记录,随机选择一条并从DB结果数组中取消分配,将其分配给winners数组,并忽略今年具有相同ID的所有其他winners 实际问题 这个方法的问题是,我当前的MYSQL查询返回了今年和过去一次比赛中所有申请者的所有记录。有没有办法
我有一个MYSQL表,用于存储年度比赛的应用程序数据。除此之外,该表还保存了参赛者的ID和该比赛申请的年份 今年,我们希望对申请的随机选择过程进行加权,这样连续申请X年的人有更大的被选中的机会 在我的PHP脚本中,我让MYSQL对象为他们应用的每一年返回1条记录,随机选择一条并从DB结果数组中取消分配,将其分配给winners数组,并忽略今年具有相同ID的所有其他winners 实际问题
这个方法的问题是,我当前的MYSQL查询返回了今年和过去一次比赛中所有申请者的所有记录。有没有办法(最好使用MYSQL)让它只返回2014年及之前的连续应用程序 由此产生的示例结果集是“1,1,1,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();
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;
这不起作用,因为它抓住了所有过去几年的记录,而不仅仅是2014年及之前的连续记录。另一种表达这个问题的方式是找到最近一年没有参赛的选手。然后,本年减去该年,即为连续年数 您可以通过在年份和参赛者之间进行交叉连接,并将左侧连接到应用程序来获得最近的一年。没有比赛的一年就是那个参赛者没有参加比赛的一年 你确实需要做一些额外的簿记来处理那些常年参加比赛的选手。最后一个问题是:
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();
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 FIDLE中的数据有何关系。你有四个赛车手,但你在问题中有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);
为什么不添加一列,说明他们为每项申请连续申请的年数?然后你只需要为每个申请者获得一行。老实说,我没有想到这一点。这可能是这个特定项目的最佳解决方案,因为对于这个特定的竞赛,还有其他因素决定了应用程序的有效性,但我也在想,对于任何未来的项目,这是否可能。id 2和4不应该是第一位的吗?你犯了一个错误,应该是
ab.race\u year=2014
这个问题看起来与你想要的有关:4个没有申请2014年的比赛,2个不一定是第一个,因为顺序是随机的;2应该返回最多的记录,这样他们就有更高的机会成为第一名。我修正了race\u year
typo@jaczes1记录需要为他们在今年之前(包括今年)连续提交的每一份申请返回。例如,如果他们在今年之前连续申请了3年,今年又申请了一次,那么他们的身份证应该被退回4次。我知道这样做既不美观也不高效,但这是我能想到的实现真正随机加权选择的唯一方法。