在连接中使用coalesce

时间:2016-03-06 16:14:17

标签: sql postgresql join coalesce

我正在编写一个查询,列出用户今天所采取的所有挑战(+得分),或者如果他在这一天没有接受任何挑战,那么他就会输出他曾经采取过的最后一项挑战。

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

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

1 个答案:

答案 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;