2012-03-06 32 views
0

我試圖使用SUM函數從3個表,然而這是因爲返回的total_filestotal_notes時有效地不靈計算行,它們兩者是相同的時至少有一個文件,然後total_files將採取與total_notes相同的值,我不明白爲什麼它這樣做。使用SUM計算相關記錄三個表

它應該計算與每條記錄相關的行數,這些記錄將以記錄列表的形式返回,並記錄每個記錄行分配給記錄的總文件數,總記錄數和總聯繫人數(文件數據,筆記和聯繫人不顯示只計數)。

我的查詢如下所示:

SELECT rec.street_number, 
     rec.street_name, 
     rec.city, 
     rec.state, 
     rec.country, 
     rec.latitude, 
     rec.longitude, 
     LEFT(rec.description, 250) AS description, 
     usr.username, 
     usr.full_name, 
     ppl.person_id, 
     ppl.first_name, 
     ppl.last_name, 
     SUM(IF(rlk.record_id = rec.record_id, 1, 0)) AS total_contacts, 
     SUM(IF(files.record_id = rec.record_id, 1, 0)) AS total_files, 
     SUM(IF(notes.record_id = rec.record_id, 1, 0)) AS total_notes, 
     (
      SELECT COUNT(DISTINCT rec.record_id) 
      FROM records rec 
      WHERE rec.marked_delete = 0 AND rec.is_archive = 0 
     ) AS total_records 
FROM 
(
    records rec 

    INNER JOIN members usr ON rec.user_id = usr.user_id 

    LEFT OUTER JOIN record_links rlk ON rec.record_id = rlk.record_id 

    LEFT OUTER JOIN people ppl ON ppl.person_id = rlk.person_id AND rlk.record_id = rec.record_id 

    LEFT OUTER JOIN files files ON files.record_id = rec.record_id 

    LEFT OUTER JOIN notes notes ON notes.record_id = rec.record_id 
) 
WHERE rec.marked_delete = 0 AND rec.is_archive = 0 
GROUP BY rec.record_id 
ORDER BY rec.submit_date DESC 
LIMIT 0, 25 

基本上,你可以看到有 SUM將數着來自那些表的相關行,但我嚴重不知道如何total_files會採取與total_notes相同的價值是否有什麼問題我在這裏做?

回答

1

這是因爲rec連接到notesfiles

假設記錄1有2個記錄和1個文件,記錄2有兩個記錄和兩個文件,記錄3有一個記錄但沒有文件。

然後表rec LEFT OUTER JOIN files ... LEFT OUTER JOIN notes看起來就像這樣:

+-----------+---------+---------+ 
| record_id | file_id | note_id | 
+-----------+---------+---------+ 
|   1 |  1 |  1 | 
|   1 |  2 |  1 | 
|   2 |  3 |  2 | 
|   2 |  3 |  3 | 
|   2 |  4 |  2 | 
|   2 |  4 |  3 | 
|   3 | NULL |  4 | 
+-----------+---------+---------+ 

注意每file_id如何被加入到每一個note_id(相同record_id內)。此外,由於您有SUM(IF(files.record_id = rec.record_id,1,0))加入條件爲files.record_id = rec.record_id,因此您實際上按record_id計算COUNT(files)*COUNT(notes)

我建議你改爲COUNT(DISTINCT files.id)COUNT(DISTINCT records.id)。在COUNT列將是對files/notes主鍵,files.record_id

SELECT rec.record_id, 
     COUNT(DISTINCT files.id) AS total_files, 
     COUNT(DISTINCT notes.id) AS total_notes 
FROM rec 
-- note: LEFT OUTER JOIN is the same as LEFT JOIN in MySQL 
LEFT JOIN files ON files.record_id=rec.record_id 
LEFT JOIN notes ON notes.record_id=rec.record_id 
GROUP BY record_id 


+-----------+-------------+-------------+ 
| record_id | total_files | total_notes | 
+-----------+-------------+-------------+ 
|   1 |   2 |   1 | 
|   2 |   2 |   2 | 
|   3 |   0 |   1 | 
+-----------+-------------+-------------+ 

當然,調整爲必要的查詢(添加這些額外的列/連接)。

+0

注 - 「total_contacts」列的處理方式相同。 – 2012-03-06 00:51:14

+0

哇!非常感謝這個詳細的答案,我希望我能給你10倍的大拇指!再次感謝。 – MacMac 2012-03-06 00:57:35