2017-07-27 50 views
1
SELECT id, author_id, max(result_score) as maxscore 
FROM submissions 
WHERE challenge_id = 10 
GROUP BY author_id 
ORDER BY maxscore DESC, created_at ASC 

此查询从具有最高分数并且最早创建的每个作者获取提交(一个)。最后,我们最终应该提交有序的提交作品,每个作者一个,所有作者都按照maxscore和created_at排序。SQL - 从每个表中选择最大值,按所述最大值排序,然后通过created_at

这在SQLite3中完美运行,但它在PostgreSQL上编译失败,因为它更严格。 PostgreSQL要求id要么通过group by子句使用,要么使用某种聚合函数。

我尝试了各种方法,使用DISTINCT ONHAVING,但无法使其工作。这种查询是否可行?如果是,那么在这里实现我想要的方式的方法是什么?

回答

2

它只能在SQLite中“完美”工作,因为SQLite已损坏。也就是说,它几乎在任何其他数据库中都会失败,因为它不是正确的SQL。

在Postgres里,你可以做你想做的使用DISTINCT ON

SELECT DISTINCT ON (author_id) id, author_id, result_score 
FROM submissions 
WHERE challenge_id = 10 
ORDER BY author_id, result_score DESC, created_at ASC; 

编辑:

如果您想通过result_score排序的最终结果,那么你可以使用子查询:

SELECT s.* 
FROM (SELECT DISTINCT ON (author_id) id, author_id, result_score 
     FROM submissions 
     WHERE challenge_id = 10 
     ORDER BY author_id, result_score DESC, created_at ASC 
    ) s 
ORDER BY result_score DESC, created_at ASC; 
+0

这是真的,这工作,但不保留我原来的查询中的逻辑。 这不会对它们进行正确排序,我们可以在结果中包含#1行,它没有最大'result_score'和最小'created_at',而是最大'author_id' – Nether

+0

@Nether。 。 。它所做的就是*完全*问题中所描述的内容:“该查询从具有最高分数并且最早创建的每个作者获得提交。” –

+0

对不起,我不清楚 – Nether

2

我设法解决这个使用rank这样的功能

SELECT id, author_id, result_score 
FROM (
    SELECT id, author_id, result_score, created_at, 
      rank() OVER (PARTITION BY author_id ORDER BY result_score DESC, created_at ASC) AS rank 
    FROM submission 
    WHERE challenge_id = %s) as sub 
WHERE sub.rank = 1 
ORDER BY result_score DESC, created_at ASC 
+0

'DISTINCT ON'是一个更好的解决方案,更短更快 - 除非你需要你的代码是ANSI兼容的(原始代码不是)。 –

+0

@GordonLinoff'DISTINCT ON'什么?它要求你在'ORDER BY'语句中有相同的参数,这对我不起作用 – Nether