2013-12-13 89 views
0

我需要限制在一個MySQL查詢中的連接,我有下面的代碼,我正在使用;限制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 

我想選擇所有從客戶表中滿足地方標準和左的連接在更新表中該客戶的最新更新的客戶。

有沒有一種簡單的方法來做到這一點,還是我需要通過PHP來做到這一點?

+3

您對group by的使用在每個其他DBMS中都是非法的。要理解MySQL的'group by'操作符鬆散(而不是斷斷續續)實現的含義,請閱讀以下內容:http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-您的查詢 - 脆弱/ –

+1

爲什麼'GROUP BY'?也許你打算使用DISTINCT運算符 – Strawberry

回答

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

你已經陷入了MySQL GROUP BY延伸的陷阱。僅僅因爲你已經把ORDER BY Date DESC這並不意味着返回的日期將是最新的。

MySQL documents狀態:

的MySQL擴展了,這樣的選擇列表可參考在GROUP未命名非聚合列BY子句

但它也接着使用GROUP的例如:

服務器可以自由選擇每組中的任何值,因此除非它們相同,否則所選值是不確定的。此外,每個組的值的選擇不能通過添加ORDER BY子句來影響。

正是出於這個原因,我總是建議,以避免impicit分組是MySQL提供,因爲它可以很容易導致非determistic查詢。

因此,您所有的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`; 

注:我已經改變了你的左連接到內部連接爲您的where子句實際上已經做到了這一點呢。如果你想要沒有更新的客戶,那麼你需要改變你的子句以從客戶中選擇,然後左鍵加入更新