2017-06-19 71 views
0

這裏是我的要求SQL - 多用和LEFT JOIN不會給預期的結果

SELECT j.* , 
    c.name as client_name , 
    s.name as supplier_name, 
    s.ID as supplier_id , 
    mt.* , 
    SUM(pb.require_followup) as nb_followup, 
    SUM(ws.worked_time) as hours_on_job, 
    SUM(iv.total) as total_price, 
    SUM(iv.hour_expected) as hours_planned, 
    j.ID as ID 

FROM $wpdb->posts j 
LEFT JOIN ".Job::$META_TABLE." mt ON mt.post_id = j.ID 
LEFT JOIN ".Job::$LINK_TABLE_JOB_CONTACT." l1 ON l1.job_id = j.ID 
LEFT JOIN ".Contact::$TABLE_NAME." c ON c.ID = l1.contact_id 
LEFT JOIN ".Supplier::$TABLE_NAME." s ON s.ID = c.supplier_id 
LEFT JOIN ".Problem::$TABLE_NAME." pb ON pb.job_id = j.ID 
LEFT JOIN ".Worksheet::$TABLE_NAME." ws ON ws.job_id = j.ID 
LEFT JOIN ".Invoice::$TABLE_NAME." iv ON iv.job_id = j.ID 

WHERE j.post_status = 'publish' 
    AND j.post_type = 'job' 
    ".implode(' ',$where_condition)." 
GROUP BY j.ID 
ORDER BY j.post_date DESC 

的問題是,對於結果SUM是錯誤的,當我LEFT JOIN另一個表。 例如,該行53給105爲nb_followup代替1

如果這個請求通過移除最後2 LEFT返回正確的結果只是JOIN:LEFT JOIN ".Worksheet::$TABLE_NAME." ws ON ws.job_id = j.IDLEFT JOIN ".Invoice::$TABLE_NAME." iv ON iv.job_id = j.ID

SELECT j.* , 
    c.name as client_name , 
    s.name as supplier_name, 
    s.ID as supplier_id , 
    mt.* , 
    SUM(pb.require_followup) as nb_followup, 
    j.ID as ID 

FROM $wpdb->posts j 
LEFT JOIN ".Job::$META_TABLE." mt ON mt.post_id = j.ID 
LEFT JOIN ".Job::$LINK_TABLE_JOB_CONTACT." l1 ON l1.job_id = j.ID 
LEFT JOIN ".Contact::$TABLE_NAME." c ON c.ID = l1.contact_id 
LEFT JOIN ".Supplier::$TABLE_NAME." s ON s.ID = c.supplier_id 
LEFT JOIN ".Problem::$TABLE_NAME." pb ON pb.job_id = j.ID 


WHERE j.post_status = 'publish' 
    AND j.post_type = 'job' 
    ".implode(' ',$where_condition)." 
GROUP BY j.ID 
ORDER BY j.post_date DESC 

而且只去掉LEFT JOIN ".Invoice::$TABLE_NAME." iv ON iv.job_id = j.ID會給15作爲結果行53

要恢復

全部要求給予105 - >錯了應該是1

去掉最後一個加入給15 - >錯了應該是1

去掉最後2加入給1 - >正確

+0

問題是,您只是通過「ID」列進行分組,但是您選擇的許多其他列沒有出現在聚合函數中。您的查詢在邏輯上不是很好定義。 –

+0

同意Tim Biegeleisen對此,你的邏輯沒有正確定義。 – XepterX

+0

我不太清楚明白,你可以嘗試提供答案嗎? – pajouk

回答

0

你需要計算SUM()s在您加入之前,否則這些行由於連接而倍增,並且這反過來導致求和中的錯誤。例如

SELECT 
     j.ID as ID 
    , pb.nb_followup 
FROM $wpdb->posts j 
LEFT JOIN (select pb.job_id, SUM(pb.require_followup) as nb_followup from ".Problem::$TABLE_NAME." pb GROUP BY pb.job_id) pb ON pb.job_id = j.ID 

你所面臨的另一個問題是,MySQL的許可證「lazy syntax」爲按組。不要使用這種懶惰的語法,否則會得到意想不到的錯誤/錯誤。避免使用GROUPE子句中的SELECT子句的每一列,除非該列使用SUM(),COUNT(),MIN(),MAX()等聚合函數,否則很容易避免。

 
select a.col1, b.col2, c.col3 , sum(d.col4) 
from a 
inner join b on a.id = b.aid 
inner join c on b.id = c.bid 
inner join d on c.id = d.cid 
group by a.col1, b.col2, c.col3