我正在编写一个查询,列出用户今天所采取的所有挑战(+得分),或者如果他在这一天没有接受任何挑战,那么他就会输出他曾经采取过的最后一项挑战。
我已经写了下面的查询,这似乎给了我想要的东西,但这似乎是一种非常复杂的实现方式。 我想知道是否有更好的方法来实现相同的结果。
SELECT COALESCE (c.id, coal) challenge_id, max(e.accuracy_score) score
FROM (select id, creation_date from challenge WHERE learner_id = $1 AND creation_date > CURRENT_DATE) c
FULL OUTER JOIN
COALESCE (
(SELECT id FROM challenge WHERE learner_id = $1 AND creation_date > CURRENT_DATE LIMIT 1),
(SELECT id FROM challenge WHERE learner_id = $1 ORDER BY creation_date DESC LIMIT 1)
) AS coal
ON coal = c.id
LEFT JOIN experience e ON COALESCE (c.id, coal)=e.challenge_id
GROUP BY COALESCE (c.id, coal) ORDER BY COALESCE (c.id, coal) ASC
答案 0 :(得分:1)
在Postgres中,我认为最简单的方法是使用窗口函数。如果您想在最近的日期遇到所有挑战:
select c.*
from (select c.*,
dense_rank() over (partition by learner
order by date_trunc('day', creation_date) desc
) as seqnum
from challenge c
) c
where seqnum = 1;
我不知道experience
表是什么。
如果你确实想要从当前日期开始,只需要最近的一次(而不是最近一次的所有挑战),那么请使用row_number()
和一些额外的日期逻辑:
select c.*
from (select c.*,
row_number() over (partition by learner
order by creation_date desc
) as seqnum
from challenge c
) c
where date_trunc('day', creation_date) = CURRENT_DATE or
seqnum = 1;