mysql - 使用SUM统计三个表的相关记录

标签 mysql count sum

我正在尝试使用 SUM 函数来计算 3 个表中的行数,但是,自从 total_filestotal_notes 返回,当至少有一个文件时,它们都是相同的,然后 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 已加入两者 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_idCOUNT(files)*COUNT(notes)

我建议您改为使用 COUNT(DISTINCT files.id)COUNT(DISTINCT reports.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 |
+-----------+-------------+-------------+

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

关于mysql - 使用SUM统计三个表的相关记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9576158/

相关文章:

php - 比较mysql中的两个逗号分隔值并获取匹配的计数

php - 通过PHP在MySQL中插入元素我得到语法错误

mysql - 计算标准化表中的记录数

javascript - 使用js获取元素的总和

php - 其中加入 1 : Many relationship?

mysql - 使用具有连接的 MySQL 子查询时的命名冲突

sql - 轨道 3 事件记录 : order and group by association count

r - 根据列中每个元素的条件计算出现次数

java - 计算偶整数总和的更好方法

Mysql左连接和求和