在联接中使用合并

Using coalesce in joins

我正在编写一个查询,列出用户今天接受的所有挑战(+ 分数),或者如果他今天没有接受任何挑战,则输出他接受过的最后一个挑战。

我写了下面的查询,它似乎给了我想要的东西,但它似乎是一种非常复杂的实现方式。 我想知道是否有更好的方法来实现相同的结果。

SELECT COALESCE (c.id, coal) challenge_id, max(e.accuracy_score) score 
FROM (select id, creation_date from challenge WHERE learner_id =  AND creation_date > CURRENT_DATE) c 
FULL OUTER JOIN
        COALESCE (
            (SELECT id FROM challenge WHERE learner_id =  AND creation_date > CURRENT_DATE LIMIT 1),
            (SELECT id FROM challenge WHERE learner_id =  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

在 Postgres 中,我认为最简单的方法是使用 window 函数。如果您想在最近的日期完成所有挑战:

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 table 是什么。

如果您真的想要当前日期的所有挑战并且只想要最近的挑战(而不是最近日期的所有挑战),那么使用 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;