Mysql 使用SUM计算三个表的相关记录

Mysql 使用SUM计算三个表的相关记录,mysql,count,sum,Mysql,Count,Sum,我正在尝试使用SUM函数来计算3个表中的行数,但是,由于返回total\u文件和total\u注释时,该函数无法有效工作,当至少有一个文件时,它们都是相同的,total_files将采用与total_notes相同的值,我不明白它为什么这样做 它应该统计与每个记录相关的行数,这些行将作为记录列表返回,每个记录行分配给该记录的总文件数、总笔记数和总联系人数(文件、笔记和联系人的数据不显示,仅计数) 我的查询如下: SELECT rec.street_number, rec.stree

我正在尝试使用
SUM
函数来计算3个表中的行数,但是,由于返回
total\u文件
total\u注释
时,该函数无法有效工作,当至少有一个文件时,它们都是相同的,
total_files
将采用与
total_notes
相同的值,我不明白它为什么这样做

它应该统计与每个记录相关的行数,这些行将作为记录列表返回,每个记录行分配给该记录的总文件数、总笔记数和总联系人数(文件、笔记和联系人的数据不显示,仅计数)

我的查询如下:

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
取相同的值,我在这里做的有什么不对吗?

这是因为
rec
同时连接到
notes
files

假设记录1有两个注释和一个文件,记录2有两个注释和两个文件,记录3有一个注释但没有文件

然后表
rec LEFT外部联接文件。。。左侧外部联接注释将如下所示:

+-----------+---------+---------+
| 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 |
+-----------+---------+---------+
注意每个
文件\u id
是如何连接到每个
注释\u id
(在同一
记录\u id
中)的。另外,由于您有
SUM(如果(files.record\u id=rec.record\u id,1,0))
,并且连接条件是
files.record\u id=rec.record\u id
,因此您实际上是在按
record\u id
计数

我建议您改为
COUNT(DISTINCT files.id)
COUNT(DISTINCT records.id)
计数中的列将是
文件
/
注释
不是
文件的主键。记录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 |
+-----------+-------------+-------------+

当然,根据需要调整您的查询(添加那些额外的列/连接)。

注意-对于
total\u contacts
列,相同的交易。哇!非常感谢你的详细回答,我希望我能给你10倍的赞誉!再次感谢。