【问题标题】:Return latest row ordered by ID while using group by使用 group by 时返回按 ID 排序的最新行
【发布时间】:2014-01-22 15:09:56
【问题描述】:

我有 2 个表,例如 A 和 B 包含一些数据

   TABLE A                 TABLE B
+----+-------+     +----+------+--------+
| id | title |     | id | a_id | status |
+----+-------+     +----+------+--------+
|  1 | apple |     |  1 |    1 |      0 |
|  2 |  eggs |     |  2 |    1 |      1 |
+----+-------+     |  3 |    1 |      2 |
                   |  4 |    1 |      3 |
                   |  5 |    1 |      0 |
                   |  6 |    1 |      1 |
                   |  7 |    2 |      0 |
                   |  8 |    2 |      1 |
                   |  9 |    2 |      2 |
                   | 10 |    1 |      0 |
                   | 11 |    1 |      3 |
                   +----+------+--------+

我想从表 A 中选择水果并加入表 B 并获取最新状态记录(按 ID)。

我的表格包含大约 10k 个水果和 100+k 个状态。

所以结果看起来像

+------+---------+------+--------+----------+
| a.id | a.title | b.id | b.a_id | b.status |
+------+---------+------+--------+----------+
|    1 |   apple |   11 |      1 |        3 |
|    2 |    eggs |    9 |      2 |        2 |
+------+---------+------+--------+----------+

我可以像这样使用 group by sql 脚本来做到这一点

SELECT * FROM a LEFT JOIN b ON a.id = b.a_id GROUP_BY a.id

但它从表 B 中获取第一项,因此结果不正确。

【问题讨论】:

    标签: mysql sql group-by subquery


    【解决方案1】:

    您可以使用substring_index()/group_concat() 技巧:

    select a.title,
           substring_index(group_concat(status order by id desc), ',', 1) as laststatus
    from b join
         a
         on a.id - b.a_id
    group by a.title;
    

    编辑:

    如果你只想要 b 的 last 记录,你可以这样做:

    select a.title, b.status
    from b join
         a
         on a.id - b.a_id
    order by b.id desc
    limit 1;
    

    【讨论】:

    • 只是一个附带问题,您可以在 GROUP BY 中使用 ORDER BY 吗?
    • @米海。 . .在group by 之后的order by 对查询结果进行排序。子查询中的order by 更值得怀疑。 ANSI 标准规定,执行子查询后不必对结果进行排序。据我所知,MySQL 文档没有解决这个问题。我会避免依赖于以特定顺序返回的子查询结果的查询。
    • substring_index、group_concat 可以解决问题!很好,但你能解释一下它是如何工作的吗?谢谢!
    • @ypercube 为什么效率不高?我已经尝试过了,在 ~0.5 秒内得到了结果,而使用子查询需要 ~55 秒
    【解决方案2】:

    所有按 b.id 排序的 regs

    SELECT * 
    FROM a
    INNER JOIN b
    ON a.ID = b.A_ID
    ORDER BY b.ID desc;
    

    只需 1 个注册。

    SELECT * FROM A
    INNER JOIN B
    ON A.ID = B.A_ID
    WHERE A.ID = (select max(B.A_ID) from B);
    

    【讨论】:

    • 编辑了我的问题,这不是解决方案,因为它返回所有行,而不是分组:)
    猜你喜欢
    • 2011-12-30
    • 1970-01-01
    • 2021-11-12
    • 2011-02-02
    • 2012-01-14
    • 1970-01-01
    • 1970-01-01
    • 2016-11-10
    • 2021-04-05
    相关资源
    最近更新 更多