在联接中使用合并
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;
我正在编写一个查询,列出用户今天接受的所有挑战(+ 分数),或者如果他今天没有接受任何挑战,则输出他接受过的最后一个挑战。
我写了下面的查询,它似乎给了我想要的东西,但它似乎是一种非常复杂的实现方式。 我想知道是否有更好的方法来实现相同的结果。
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;