分组后找到某成员及其前面的成员

【问题】

We have a query like this:

SELECT u.email, st.value as score,

date_format(FROM_UNIXTIME(st.timemodified),'%d-%m-%Y %H:%i:%s' ) as fecha,

IF(st.value >= 70, 'YES', 'NO') as result

FROM  user u

LEFT  JOIN scorm_scoes_track st ON st.userid = u.id

LEFT  JOIN scorm_scoes as ss ON ss.scorm = st.scormid

WHERE (st.element='cmi.score.raw'  OR st.element='cmi.core.score.raw')

ORDER  BY u.id, st.timemodified
+------------------+------------+---------------------+----------+

| email | score | fecha | result |

+------------------+------------+---------------------+----------+

| test@test.es | 45| 14-03-2015  17:10:18 | NO |

| test@test.es | 65| 14-03-2015  17:12:42 | NO |

| test@test.es | 70| 14-03-2015  17:15:04 | YES |

| test@test.es | 60| 14-03-2015  17:17:16 | NO |

| test@test.es | 65| 14-03-2015  17:17:16 | NO |

User passes the test if result is greater/equal than 70. We need that only results until 70 (when test is passed) will be shown.

In this case, we need this result:

| test@test.es | 45| 14-03-2015  17:10:18 | NO |

| test@test.es | 65| 14-03-2015  17:12:42 | NO |

| test@test.es | 70| 14-03-2015  17:15:04 | YES |

Because results after score is >= 70 have to be discarted

【回答】

SQL 不擅长有序运算,用窗口函数写出来的语句很难懂。这种问题用 SPL 来做,代码直观易懂:



A

1

$select * from tb1 order by score

2

=A1.group(email).conj(~.to(~.pselect(score==70)))

A1: 查询表数据

A2: 对 email 分组,使用 conj 做成员合并,获取满足条件的记录(用 pselect 选出第 1 条符合条件的记录序号,to 做区间取数,~ 表示每个组)。

复杂的组内计算和有序计算大都可以用集算器来简化,并且集算器还提供了 JDBC 接口,可以像数据库一样嵌入到应用程序中,用起来很简单,可参考Java 如何调用 SPL 脚本