Php 根据最新的相关对象进行查询
我有两个具有1-N关系的实体,如下所示:Php 根据最新的相关对象进行查询,php,mysql,symfony,doctrine,Php,Mysql,Symfony,Doctrine,我有两个具有1-N关系的实体,如下所示: table_a ------- id name table_b ------ id table_a_id name status created_at 我正在MySQL中寻找一种方法,尤其是使用ORM查询表a,表b上有一个“where”子句,它只影响最后一个关联的表b记录 假设我有以下记录: table_a ---------------------------- id | name ----------------------------
table_a
-------
id
name
table_b
------
id
table_a_id
name
status
created_at
我正在MySQL中寻找一种方法,尤其是使用ORM查询表a,表b上有一个“where”子句,它只影响最后一个关联的表b记录
假设我有以下记录:
table_a
----------------------------
id | name
----------------------------
1 | john
2 | mary
3 | chuck
table_b
--------------------------------------------------
id | table_a_id | name | status | created_at
--------------------------------------------------
1 | 1 | blue | 1 | 2000-01-01
2 | 1 | red | 1 | 2012-12-31
3 | 2 | yellow | 1 | 2000-01-01
4 | 2 | green | 0 | 2012-12-31
所以我想告诉MySQL/Doctrine:
把桌子给我
哪些有表b记录
最后一个相关元素的状态=1(根据创建的_at字段)
这只应返回:
table_a
----------------------------
id | name
----------------------------
1 | john
不确定“原则”,但MySQL查询可以
select
a.ID,
a.Name
from
table_b B
join table_a A
on B.table_a_id = A.ID
where
B.status = 1
order by
B.Created_At DESC
limit 1
根据这本书,这种带有适当索引的连接通常比子查询性能更好。因此,也可以尝试这种方法:
SELECT a.*
FROM table_a a
JOIN table_b b1
ON b1.table_a_id = a.id
AND b1.status = 1
LEFT JOIN table_b b2
ON b2.table_a_id = a.id
AND b2.created_at > b1.created_at
WHERE b2.table_a_id IS NULL
如果表b中状态为1
的两行可能具有相同的表a\u id
和在日期创建的,则需要不同的,以避免重复:
SELECT DISTINCT a.*
FROM table_a a
JOIN table_b b1
ON b1.table_a_id = a.id
AND b1.status = 1
LEFT JOIN table_b b2
ON b2.table_a_id = a.id
AND b2.created_at > b1.created_at
WHERE b2.table_a_id IS NULL
我不想限制查询的结果。您的查询总是只返回一个表\一条记录。限制必须只涉及关系。这是关于MySQL还是关于教义?在MySQL中,这是一个典型的最大n个组的问题(我们这里甚至有一个标签),解决方案是基于我可以使用本机SQL的原则,所以问题主要是MySQL。谢谢你的url,我正在测试此解决方案。我无法编写正确的查询。。。你能给我上一个例子的上下文中的正确语法吗?我没有理解最后一行(其中为NULL),它的用途是什么?查询将表b
连接到自身,但是它确保b2.created\u at>b1.created\u at
。然后,在
处创建的具有最高值的联接行将不会有来自b2
的结果,因为这使得
实际上不可能。反过来,这意味着b2.table_a_id
(或b2
中的任何内容)为空。这意味着b1
中的适用行就是您要查找的行。谢谢@Simonatmso.net和Marcus,现在已经清楚了,它就像一个符咒一样工作!两年后,我有一个问题:如果我只想要表a中的记录,其中b1.status=1,但这些记录不是最新的(任何表b都匹配,但不是创建值最高的表?我想只需将where子句更改为其中b2.table\U id不为NULL
)。