【问题标题】:SQL - Select maximum from each table, ordered by said maximum and then by created_atSQL - 从每个表中选择最大值,按所述最大值排序,然后按 created_at
【发布时间】:2017-07-27 11:03:04
【问题描述】:
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 排序

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

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

【问题讨论】:

    标签: sql postgresql sqlite


    【解决方案1】:

    我设法使用像这样的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
    

    【讨论】:

    • DISTINCT ON 是一个更好的解决方案,更短、更快——除非您需要您的代码符合 ANSI(原始代码不符合)。
    • @GordonLinoff DISTINCT ON 什么?它要求您在 ORDER BY 语句中具有相同的参数,这对我不起作用
    【解决方案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;
    

    【讨论】:

    • 没错,这可行,但不保留我原始查询中的逻辑。这不会正确地对它们进行排序,结果中的 #1 可能是没有最大 result_score 和最小 created_at 的行,而是最大的 author_id
    • @Nether 。 . .这样做正是问题中描述的:“此查询从每个得分最高且创建时间最早的作者那里获取提交。”
    猜你喜欢
    • 1970-01-01
    • 2021-04-03
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    • 2018-07-09
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    相关资源
    最近更新 更多