表格答案:
Answer ID | User ID | Question ID | deleted
1 | 1 | 1 | f
2 | 1 | 2 | f
3 | 1 | 2 | f
4 | 1 | 1 | t
5 | 2 | 1 | f
6 | 2 | 2 | f
7 | 2 | 2 | f
我想使用最新答案(基于最高ID)选择(userID, questionID)
上所有与众不同的答案,然后从此结果集中删除所有具有deleted = t
的条目。
所以我的结果应该是
Answer ID | User ID | Question ID | deleted
3 | 1 | 2 | f
5 | 2 | 1 | f
7 | 2 | 2 | f
我想我们不能使用从界面生成的查询方法来做到这一点?我改用@Query
批注:
@Query("SELECT a1 FROM answer a1 WHERE ... ")
findLatestAnswers();
我想到了这个(sql提琴:http://sqlfiddle.com/#!15/02339/8/0),甚至没有使用distinct
或group by
或order by
。它正在完成任务,但对于较大的数据集而言似乎效率很低?什么是更快的陈述?
SELECT * FROM answer a1
WHERE NOT EXISTS ( -- where no newer answer exists
SELECT * FROM answer a2
WHERE a1.user_id = a2.user_id
AND a1.question_id = a2.question_id
AND a1.id < a2.id
)
AND a1.deleted = FALSE;
答案 0 :(得分:1)
使用distinct
或group by
或聚合函数没有问题。这些在数据仓库或分析软件中至关重要,在该软件中,每个请求中都会处理数百万或记录(数十亿和数万亿的大数据)。
唯一的调整是根据您的数据和查询生成索引。
scanrio所需的功能是max
。您必须按以下步骤选择max
中的anser_id
中的user_id, question_id
:
解决方案1
@Query("select max(answer) from Answer answer where answer.deleted = false group by answer.userId, answer.questionId")
List<Answer> findLatestAnswersByUserQuestionNotDeleted();
此语句返回4条记录,因为,如果您不考虑删除答案,那么问题1中用户1的最新答案将变为1。
我不知道您为什么不考虑这一点,但我会照原样回答您的问题。
因此,您必须按照您的描述以编程方式发布过滤器,以便@Query
变为:
@Query("select max(answer) from Answer answer group by answer.userId, answer.questionId")
List<Answer> findLatestAnswersByUserQuestion();
您同样有4条记录,因为还存在已删除并且必须以编程方式对其进行过滤
解决方案2(两个查询,因为您需要忽略已删除并且不考虑旧查询)
第1步-找到答案的id,包括已删除(仅id):
@Query("select max(answer.id) from Answer answer group by answer.userId, answer.questionId")
List<Long> findLatestAnswersId();
第2步-通过ID(不包括已删除)加载答案
List<Answer> findAllByDeletedIsFalseAndIdIn(List<Long> ids);
解决方案3(一个查询)
@Query("select answer from Answer answer where answer.deleted = false and answer.id in (select max(inAnswer.id) from Answer inAnswer)")
List<Answer> findLastestNotDeleted()