【问题标题】:Retrieving aggregate values from multiple tables从多个表中检索聚合值
【发布时间】:2017-10-18 06:35:27
【问题描述】:

我正在尝试从不同的表中获取一些聚合值,但我的问题是它们被错误地返回,即作为彼此相乘。

我有这些表:

Institutes
----------
ID
name

Conversions
-----------
ID
institute_id
training_id

Trainings
---------
ID
institute_id

我想要获取 Institute.name、转化次数和培训次数。我可以获取名称和其中一个聚合值,但是当我尝试获取这两个值时,它会返回错误的数字,因为它将重复每次训练的所有转换(或相反)。

我正在使用这个 SQL:

SELECT    Institute.id
          ,Institute.name 
          ,Institute.friendly_url
          ,count(Training.`id`) as totalTrainings
          ,count(Conversion.`id`) AS totalConversions
FROM      institutes Institute  
          LEFT JOIN    trainings Training     ON Institute.`id` = Training.`institute_id`       
          LEFT JOIN    conversions Conversion ON Training.`institute_id` =   Conversion.`institute_id`
GROUP BY  1,2,3

稍后我需要添加更多表,使用相同的结构,并且唯一的目的是检索聚合。我可以通过使用多个查询使其工作,但是当我想要过滤数据时,我会遇到无法使用正确排序、分页和问题的问题。

创建视图也是我一直在考虑的解决方案,但我仍然需要一些 SQL 来创建该视图。

我也尝试过修改GROUP BY,但无济于事。

更新 我现在在我的联接中使用子查询,这似乎有效。有没有更优化的解决方案?

SELECT    Institute.id
          ,Institute.name 
          ,Institute.friendly_url
          ,Training.total
          ,Conversion.total
FROM      institutes Institute 
          LEFT JOIN (SELECT institute_id, count(id) AS total
                     FROM `trainings`
                     GROUP BY institute_id) AS Training ON Training.institute_id = Institute.id
          LEFT JOIN (SELECT institute_id, count(id) AS total
                     FROM `conversions`
                     GROUP BY institute_id) AS Conversion ON Conversion.institute_id = Institute.id

【问题讨论】:

    标签: mysql aggregate left-join


    【解决方案1】:

    试试看。恕我直言,做一个单独的子查询更好。并且看起来更好,更容易阅读查询。

    SELECT    
    Institute.id  
    ,Institute.name   
    ,Institute.friendly_url  
    ,(SELECT count(Training.`id`) FROM trainings Training WHERE Institute.`id` = Training.`institute_id` LIMIT 1) as totalTrainings   
    ,(SELECT count(Conversion.`id`) FROM conversions Conversion ON Institute.`id` =   Conversion.`institute_id`  LIMIT 1) AS totalConversions  
    FROM institutes Institute
    

    【讨论】:

    • 这为选择中的第一个(和第二个)子查询提供了语法错误。顺便说一句,子查询是个好主意。在我的联接中使用子查询似乎给出了正确的计数。
    • 我改了一下,再试一次。我看不出还有什么可能导致我的答案中的子查询出现问题。运行示例时遇到什么错误?列名是否正确?
    • 这行得通,谢谢。不过,我选择在我的帖子更新中使用子查询方法,因为我认为它更容易阅读并且速度也更快。谢谢!
    【解决方案2】:

    (意识到这是两年后) 我相信您的 COUNT 子句中的 DISTINCT 可以解决问题。

    SELECT    Institute.id
              ,Institute.name 
              ,Institute.friendly_url
              ,count(DISTINCT Training.`id`) as totalTrainings
              ,count(DISTINCT Conversion.`id`) AS totalConversions
    FROM      institutes Institute  
              LEFT JOIN    trainings Training     ON Institute.`id` = Training.`institute_id`       
              LEFT JOIN    conversions Conversion ON Training.`institute_id` =   Conversion.`institute_id`
    GROUP BY  1,2,3
    

    【讨论】:

      猜你喜欢
      • 2017-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多