我需要限制mysql查询中的连接,我有以下代码,我正在使用;
select customer.`name`, customer.`retainer_value`, updates.`date`
from updates
left join customer on customer.id = updates.`clientid`
WHERE customer.`retainer_value` < 250
AND customer.switchedoff = 'N'
AND customer.companyid <> 3
AND customer.retainer_value > 20
group by updates.clientid
order by updates.date DESC
我正在尝试从customers表中选择满足where条件的所有客户,并在该客户的更新表中加入最新更新。
有没有一种简单的方法可以做到这一点,还是需要通过PHP来实现?
答案 0 :(得分:1)
首先,如果您希望保留符合过滤条件的所有客户,则需要按正确的顺序执行left join
。这意味着customer
表应该位于left join
。
然后,如果您想要最近的日期,请使用max()
:
select c.`name`, c.`retainer_value`, max(u.`date`)
from customer c left join
updates u
on c.id = u.`clientid`
WHERE c.`retainer_value` < 250 AND c.switchedoff = 'N' AND c.companyid <> 3 AND
c.retainer_value > 20
group by c.id
order by max(u.`date`) DESC
答案 1 :(得分:1)
你已陷入MySQL GROUP BY扩展的陷阱。仅仅因为你放了ORDER BY Date DESC
并不意味着返回的日期将是最新的。
MySQL扩展了GROUP BY的使用,以便选择列表可以引用未在GROUP BY子句中命名的非聚合列
但它还接着说:
服务器可以自由选择每个组中的任何值,因此除非它们相同,否则所选的值是不确定的。此外,添加ORDER BY子句不会影响每个组中值的选择。
正是出于这个原因,我总是建议避免MySQL提供的不正当分组,因为它很容易导致非确定性查询。
因此,您的所有ORDER BY
子句正在执行的操作是,每个客户端都会重新获得任何日期,它会按照所选日期的顺序对最终结果集进行排序。如果您想要最新的更新日期,确定性地执行此操作的唯一方法是使用MAX
函数:
select customer.`name`, customer.`retainer_value`, MAX(updates.`date`) as Date
from updates
inner join customer on customer.id = updates.`clientid`
WHERE customer.`retainer_value` < 250
AND customer.switchedoff = 'N'
AND customer.companyid <> 3
AND customer.retainer_value > 20
group by updates.clientid, customer.`name`, customer.`retainer_value`;
N.B我已经将你的左连接更改为内连接,因为你的where子句无论如何已经有效地完成了这个。如果您希望客户没有更新,那么您需要更改您的条款以从客户中进行选择,然后将加入更新为