【问题标题】:SQL how to find ids of rows with largest created_date inside a grouped bySQL如何在分组中查找具有最大created_date的行的ID
【发布时间】:2019-12-20 08:13:02
【问题描述】:

我有一个三列的表格:

id | created_at | original_id
a1 | 2019-12-10 | a
a2 | 2019-12-12 | a
a3 | 2019-12-11 | a
b1 | 2019-12-10 | b
b2 | 2019-12-09 | b

我想在所有具有相同 original_id 的行中查找具有最大 created_at 的所有行的 id

(背景:该表存储一个元素的“历史”,因此每次更改或删除时,都会创建一个新的历史条目。我想知道最新历史条目的ID每个元素/每个 original_id)

所以我对上述示例数据的预期结果是:

id | MAX(created_at) | original_id
a2 | 2019-12-12      | a
b1 | 2019-12-10      | b

我尝试了几种使用子查询和分组依据的方法,但我无法真正获得分组依据内的最大值

SELECT a.id, a.original_id, a.created_at FROM notes.test AS a
WHERE a.created_at = (SELECT MAX(b.created_at)
                FROM notes.test AS b
                WHERE b.original_id = a.original_id) 

在我弄清楚如何用 sql 编写这个查询之后,我还需要将它与 Java-Spring-Repository 一起使用,所以也欢迎任何关于如何实现它的想法

【问题讨论】:

  • 您的查询工作正常,您只需要将表别名添加到test 的第一个实例,即SELECT a.id, a.original_id, a.created_at FROM test a sqlfiddle.com/#!9/af76c/2
  • 我同意@nick 的说法,查询工作正常。见sqlfiddle.com/#!9/4bdd3d/1
  • 是的,我也发现了^^非常感谢您的帮助!

标签: java mysql sql spring


【解决方案1】:

在 MySQL 8 中,您可以使用窗口函数:

select original_id
     , id as last_id
     , created_at
  from ( select original_id
              , created_at
              , id
              , row_number()
                  over (partition by original_id
                        order by created_at desc)
                  as row_num
           from test
       ) x
 where row_num = 1

输出

original_id | last_id | created_at
a           | a2      | 2019-12-12
b           | b1      | 2019-12-10

请参阅 db-fiddle.com 上的 DEMO

【讨论】:

  • 感谢您的回复。不幸的是,我不确定 @query-notation 中的默认 spring 存储库是否可以做到这一点,所以我认为我不能使用这样的查询。但是直接在数据库上执行确实解决了问题。
  • @Juliette 真的,我认为nativeQuery = true 的全部目的是您可以编写数据库服务器能够理解的任何内容。见:Is it possible to use raw SQL within a Spring Repository
  • uuuh 我不知道。非常感谢您的提示,我一定会尝试的! :)
【解决方案2】:

我希望这会有所帮助:

    with cte1 as (
        select a.id, a.created_at, a.original_id
        from table_name a
    ),
    cte2 as (
        select max(b.created_at) as created_at, b.original_id
        from table_name b
        group by b.original_id
    )
    select c1.id, c2.created_at, c2.original_id
    from cte1 c1
    join cte2 c2 on c2.created_at = c1.created_at and c1.original_id = c2.original_id

【讨论】:

  • 嗨 :) 感谢您的建议。不幸的是,我认为即使此查询有效,我也无法在 Java Spring Repository 或 @Query 中使用它
  • @Juliette 哦,当然。我很高兴你找到了答案:)
【解决方案3】:

免责声明:此答案并未直接回答问题,而是通过更改数据库架构提出了另一种方法

感谢所有建议,我刚刚找到了一个更优雅的解决方案,并且可以更轻松地与 Java Spring 一起使用(据我所知,@Query 注释中不支持 FROM 子句中的子查询)

还解决了两个item的created_at日期相同的问题,不重复创建。

我只是将 id-column 从 UUID 更改为自动递增的 int-column,这样我就可以通过以下方式获得结果:

SELECT * FROM notes.test WHERE id IN (SELECT MAX(id) FROM notes.test GROUP BY parent_id)

【讨论】:

  • 当您的要求是“拥有最大的created_at 并且查询甚至不使用created_at 列时,这怎么能成为解决方案? --- 请记住,您的id 列是文本,因此id 的值'a10' 不大于id 的值'a9',这意味着MAX(id) 不起作用。
  • 我的要求也是“我想知道每个元素/每个 original_id 的最新历史条目的 id”。我只是认为我在问题中描述的方式是最好的解决方案
  • 您的第一句话没有这么说,问题也没有提到修改架构是一种选择。问题是:我有这个架构,如何编写查询?这意味着这不是问题的答案。
  • 很抱歉我的问题没有更清楚。我试图表达这个概念仍在发展中,但似乎我在这方面失败了。您对如何编辑我的问题有任何建议吗?我将不胜感激
  • StackOverflow 上的问题和答案应该是编程问题解决方案的存储库,允许其他人找到已经回答的解决方案。没有其他人会发现 “更改架构” 答案对于说 “我有这个架构,如何编写查询?” 的问题很有用,尤其是当有查询时与工作解决方案。 --- 无论如何,如果不编辑答案,我就无法删除否决票,所以如果您可能提到 预先 (第一句),这个答案会因更改架构而偏离,我'将删除反对票。
猜你喜欢
  • 2019-11-30
  • 1970-01-01
  • 2017-10-15
  • 1970-01-01
  • 2015-10-15
  • 2021-05-24
  • 1970-01-01
  • 1970-01-01
  • 2019-04-11
相关资源
最近更新 更多