mysql - 使用多个连接 sql 查找多个计数

标签 mysql sql count left-join inner-join

我有四个结构如下的表

Destinations:
id , destination_name 

Activities:
id , destination_id

Attractions:
id , destination_id 

Fair :
id , destination_id

我正在使用

SELECT  d.id AS id, 
        d.destination_name AS destination_name,
        d.destination_type AS destination_type, 
        d.is_active AS is_active, 
        d.meta_description AS meta_description, 
        d.meta_keywords AS meta_keywords, 
        d.meta_title AS meta_title, 
        COUNT(att.id) AS attractions, 
        COUNT(act.id) AS activitys, 
        COUNT(f.destination_id) AS fairs 
FROM    destinations AS d 
        LEFT JOIN attractions AS att 
            ON d.id= att.destination_id 
        LEFT JOIN category_destination_ref AS act 
            ON d.id = act.destination_id 
        LEFT JOIN fairnfestival AS f 
            ON d.id = f.destination_id 
GROUP BY d.id 
ORDER BY d.id DESC 

但它给了我“景点”和“集市”列的总和

最佳答案

你的问题是你加入了不止一个 1-n 关系,所以用最简单的术语来说,如果你有 2 个景点和每个目的地的两个集市,一个简单的连接将为你提供集市和景点的笛卡尔积:

DestinationID   FairID  AttractionID
1               1       1
1               1       2
1               2       1
1               2       2

如您所见,FairID 只有 2 个值,但有 4 行,因此计数将产生 4,而不是您期望的 2。

您要么需要使用 COUNT(DISTINCT att.id) AS attractions,例如:

SELECT  d.id AS id, 
        d.destination_name AS destination_name,
        d.destination_type AS destination_type, 
        d.is_active AS is_active, 
        d.meta_description AS meta_description, 
        d.meta_keywords AS meta_keywords, 
        d.meta_title AS meta_title, 
        COUNT(DISTINCT att.id) AS attractions, 
        COUNT(DISTINCT act.id) AS activitys, 
        COUNT(DISTINCT f.id) AS fairs 
FROM    destinations AS d 
        LEFT JOIN attractions AS att 
            ON d.id= att.destination_id 
        LEFT JOIN category_destination_ref AS act 
            ON d.id = act.destination_id 
        LEFT JOIN fairnfestival AS f 
            ON d.id = f.destination_id 
GROUP BY d.id 
ORDER BY d.id DESC;

或者将聚合移动到子查询:

SELECT  d.id AS id, 
        d.destination_name AS destination_name,
        d.destination_type AS destination_type, 
        d.is_active AS is_active, 
        d.meta_description AS meta_description, 
        d.meta_keywords AS meta_keywords, 
        d.meta_title AS meta_title, 
        COALESCE(att.attractions, 0) AS attractions, 
        COALESCE(act.activitys, 0) AS activities, 
        COALESCE(f.fairs, 0) AS fairs
FROM    destinations AS d 
        LEFT JOIN 
        (   SELECT  att.Destination_ID, COUNT(att.id) AS Attractions
            FROM    attractions AS att
            GROUP BY att.Destination_ID
        ) AS att 
            ON d.id = att.destination_id 
        LEFT JOIN 
        (   SELECT  act.Destination_ID, COUNT(act.id) AS activities
            FROM    category_destination_ref AS act
            GROUP BY act.Destination_ID
        ) AS act
            ON d.id = act.destination_id 
        LEFT JOIN 
        (   SELECT  f.Destination_ID, COUNT(f.id) AS fairs
            FROM    fairnfestival AS f
            GROUP BY f.Destination_ID
        ) AS f
            ON d.id = f.destination_id
ORDER BY d.id DESC;

我怀疑前者在 MySQL 中表现更好,因为它不能很好地处理子查询,但如果您需要开始执行 SUM,则后者是必需的,因为 SUM(DISTINCT 将不起作用.

关于mysql - 使用多个连接 sql 查找多个计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20097172/

相关文章:

mysql - 我怎样才能让这个mysql查询更有效率呢?

python - 计算时间序列中的连续值

php - 将 XML 导入 WordPress

php - 如何在 PHP 和 Ubuntu 中设置多个依次运行的 cron 作业

mysql - JOIN 多个表,结果在同一列上

c++ - mysql和c++连接

mysql - 连续行之间每人之间的时间差

count - 生产中的 Redis 扫描计数

c - 为什么人口计数的输入参数必须是无符号的

php - mysql 如何获取某一天的最大值?