我的简单表格以这种方式(4个字段)和超过100行格式化:
id结果id_user数据
1 0 11 2016-10-15 18:00:00
2 0 13 2016-10-15 18:00:00
3 0 16 2016-10-15 18:00:00
4 0 24 2016-10-15 18:00:00
5 0 6 2016-10-15 18:00:00
6 3 3 5 2016-10-15 18:00:00
7 3 45 2016-10-15 18:00:00
8 3 3 66 2016-10-15 18:00:00
9 3 4 2016-10-15 18:00:00 < br /> 10 3 33 2016-10-8 17:00:00
11 1 55 2016-10-8 17:00:00
12 1 101 2016-10-8 17:00:00
...
我每周用这个逻辑保存10条记录: 如果一支球队获胜,我将为球队的每个成员节省3分,为球队的每个成员保留0分。 (如果他们抽签,我将为所有10名成员保存1分),依此类推。
现在我的问题是如何提取保存在此表中的前3名球员,至少打了5场比赛,并且在最后5场比赛中有主要得分。
我用这种方式格式化了我的查询:
(SELECT m1.id_user, m1.data, SUM(result) AS ris
FROM my_table m1
JOIN(SELECT id_user
FROM my_table
GROUP BY id_user
HAVING COUNT(id_user) >= 5) m2
ON m2.id_user = m1.id_user
GROUP BY id_user
ORDER BY m1.data DESC)
ORDER BY ris DESC LIMIT 3;
但是这个查询考虑了所有比赛中的得分量,而不仅仅是最近5场比赛!如果有可能,如何在我的查询中插入这个条件?
感谢您的帮助。
答案 0 :(得分:0)
您可以尝试将SUM(结果)放到子查询中。
SELECT m1.id_user,m1.data,result AS ris from my_table m1 JOIN(SELECT id_user, SUM(result)as result FROM my_table GROUP BY id_user HAVING COUNT(id_user)&gt; = 5)m2 ON m2.id_user = m1.id_user GROUP BY id_user ORDER BY m1.data DESC )ORDER BY ris DESC LIMIT 3;
答案 1 :(得分:0)
实际上并没有一种非常有效的方法,但即使没有MySQL支持窗口函数,它也是可能的。它有助于保持简单,分数是单个数字,并且只有两个可能的非零分数。
select id_user,
3*length(replace(replace(left(group_concat(result order by data desc separator ''), 5), '0', ''), '1', ''))
+length(replace(replace(left(group_concat(result order by data desc separator ''), 5), '0', ''), '3', ''))
as score_sum
from my_table
group by 1
having count(*) >= 5
order by 2 desc
limit 3;
打破它:
group by 1
是group by id_user
的缩写(select中的第一个值),因此每个用户只返回一行。
group_concat(result order by data desc separator '')
连接用户的所有分数,最近一次,没有在它们之间添加分隔符字符串,为用户生成类似'033101003'的字符串。 group_concat
将在某个(可配置的)长度之后截断数据并产生警告,但这不是关注的问题。
left(..., 5)
为用户提供最左边(最近)的五个分数(例如'03310')。
replace(...,'0','')删除0,所以上面的例子变成'331'。
我们通过取这个字符串计算多少3个,用''替换1'(生成'33'),然后取长度(2)。
同样地,我们通过取这个字符串计算多少1,用''(生成'1')替换3'并取长度(1)。
3*...+...
通过将3的数量加到1的数量上来计算得分的总和(2 * 3 + 1是0,3,3,1中最近五个得分的7的总和) ,0,1,0,0,3)。
我采用这种方法,因为只有两个非零分数要处理。如果有更多,我会使用不同的计数技巧。而不是删除我不想要的数字,我会计算我做的那些。你这样说(length(string)-length(replace(string,searchstring,'')))/length(searchstring)
。例如。要计算abccbacba中的c,你删除c(产生abbaba)并从原始字符串的长度中减去(6)的长度(9,得到3的结果)。