如何使用 MySQL 选择最后一行匹配条件的父/子关系的最后一个子行

Posted

技术标签:

【中文标题】如何使用 MySQL 选择最后一行匹配条件的父/子关系的最后一个子行【英文标题】:How do I select the last child row of a parent/child relationship where the last row matches a condition using MySQL 【发布时间】:2011-09-15 11:56:06 【问题描述】:

我的问题类似于previous poster。

他的问题是:“仅使用 mysql 我想选择父子关系的最后每个子行,其中子行按时间戳排序”。

我想这样做,但我也想只选择 status 为 1 的子行。

我的表是fobs_inventoryfobs_inventory_history。我想要每个fobs_inventory 的最新(即:最近时间戳)fobs_inventory_history 记录,其中fobs_inventory_history.status = 1

-------------------------------
| fobs_inventory              |
-------------------------------
| inv_id | other fields       |
-------------------------------
| 1      | ...                |
| 2      | ...                |
| 3      | ...                |
-------------------------------

----------------------------------------------
| fobs_inventory_history                     |
----------------------------------------------
| id | inv_id | status | created_at          |
----------------------------------------------
| 1  | 1      | 0      | 2011-10-11 10:00:00 |
| 2  | 1      | 1      | 2011-08-01 10:00:00 |
| 3  | 1      | 0      | 2011-07-01 10:00:00 |

| 4  | 2      | 1      | 2011-09-11 14:00:00 |
| 5  | 2      | 0      | 2011-08-01 12:00:00 |
| 6  | 2      | 2      | 2011-07-01 00:00:00 |

| 7  | 3      | 1      | 2011-10-11 14:00:00 |
| 8  | 3      | 2      | 2011-08-01 12:00:00 |
| 9  | 3      | 0      | 2011-07-01 00:00:00 |
----------------------------------------------

生成类似于下表的结果集的最佳 SQL 语法是什么?

--------------------------------------------------------------------
| inv_id | fob_inventory_history_id | status | created_at          |
--------------------------------------------------------------------
| 2      | 4                        | 1      | 2011-09-11 14:00:00 |
| 3      | 7                        | 1      | 2011-10-11 14:00:00 |
--------------------------------------------------------------------

我只想返回最近时间戳的status 为 1 的行。

编辑

在做了更多工作之后,我想出了我在此处发布的解决方案,因为它可能会帮助其他尝试做同样事情的人。

基本上解决方案是在子选择之外选择与 MAX() 和 GROUP BY 关联的所有相应字段,检查一下:

select h.id, h.fob_id, h.inv_id, h.status, h.created_at from fobs_inventory_history h, (
    select id, inv_id, status, max(created_at) as ts
    from fobs_inventory_history
    group by inv_id
) h2
where h.created_at = h2.ts
and h.inv_id = h2.inv_id 
and h.fob_id = 1 and h.status = 1

【问题讨论】:

【参考方案1】:

非常感谢您发布此消息!解决了困扰我两天的问题。 我需要包含一些父信息,所以我在这个查询中添加了一个 JOIN,如下所示:

select i.custid, i.custorderno, h.id, h.fob_id, h.inv_id, h.status, h.created_at from fobs_inventory_history h, (
    select id, inv_id, status, max(created_at) as ts
    from fobs_inventory_history
    group by inv_id
) h2
INNER JOIN invoice AS i ON h2.inv_id = i.inv_id
where h.created_at = h2.ts
and h.inv_id = h2.inv_id 
and h.fob_id = 1 and h.status = 1

【讨论】:

【参考方案2】:

试试

select 
   inv_id, id AS fob_inventory_history_id, status, created_at from  fobs_inventory_history 
where
   status = 1
order by created_at desc
LIMIT 2

您可以根据要获取的行数来修改限制

【讨论】:

以上是关于如何使用 MySQL 选择最后一行匹配条件的父/子关系的最后一个子行的主要内容,如果未能解决你的问题,请参考以下文章

选择所有子行都符合条件的父行

MySQL 子查询

仅选择与选择器匹配的父节点

伪类选择符

jQuery选择器

如何实现子查询以选择与三个主题中的两个主题匹配的行?