简体   繁体   中英

wrong count on the multiple joins with the same table

i have 2 tables

1 - coupons

2 - tractions

for each coupon there might be couple of rows in tractions table I want to have list of all coupons and count of its tractions under different condition

    SELECT `coupons`.`id` ,
            count( tractions_all.id ) AS `all` , 
            count( tractions_void.id ) AS void, 
            count( tractions_returny.id ) AS returny,
            count( tractions_burned.id ) AS burned
      FROM `coupons`
               LEFT JOIN `tractions` AS `tractions_all` 
                         ON `coupons`.`id` = `tractions_all`.`coupon_parent`
               LEFT JOIN `tractions` AS `tractions_void` 
                         ON `coupons`.`id` = `tractions_void`.`coupon_parent`
                         AND `tractions_void`.`expired` =1
               LEFT JOIN `tractions` `tractions_returny` 
                         ON `tractions_returny`.`coupon_parent` = `coupons`.`id`
                         AND `tractions_returny`.`expired` =11
               LEFT JOIN `tractions` `tractions_burned` 
                         ON `tractions_burned`.`coupon_parent` = `coupons`.`id`
                         AND `tractions_burned`.`expired` =0
                         AND '2014-02-12'
     WHERE `coupons`.`parent` =0
  GROUP BY `coupons`.`id`

right now only one of my coupons has 2 traction on both are burned traction other coupons have no tractions at all

here is the result

在此处输入图片说明

as you can see coupon with id=13 has 4 traction while it should be 2 ... what am i doing wrong ? if i remove the last join it works fine and i get 2

You are aggregating along multiple dimensions at one time, resulting in a cartesian product for each id.

If your data volume is not very large, the easiest way to fix this is using distinct :

SELECT `coupons`.`id` ,
       count(distinct tractions_all.id ) AS `all` , 
       count(distinct tractions_void.id ) AS void, 
       count(distinct tractions_returny.id ) AS returny,
       count(distinct tractions_burned.id ) AS burned

If your data is large, then you will probably need to aggregate values as subqueries first and then do the joins.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM