2016-11-30 31 views
3

有了這個簡化的結構:MYSQL:同一個表上的兩個連接成爲雙重分組​​計數。如何解決它?

customers 
----------------------- 
id 
name 
salesagents_id  (each client has their own sales agent assigned) 

salesagents 
----------------------- 
id 
name 


visits 
----------------------- 
customers_id 
salesagents_id 
date 

我需要讓所有的客戶名單,再加上三個附加字段:

  1. 銷售代理的名稱分配給客戶端
  2. 收到瀏覽次數by salesperson
  3. 上個月收到的訪問次數

這是查詢我到目前爲止:

SELECT clients.*, salesagents.name, COUNT(v1.id) as visits_number, COUNT(v2.id) as visits_number_last_month 
FROM `clients` 
LEFT JOIN `salesagents` ON `clients`.`salesagents_id`=`salesagents`.`id` 
LEFT JOIN `visits` as `v1` ON `clients`.`id` = `v1`.`clients_id` 
LEFT JOIN `visits` as `v2` ON `clients`.`id` = `v2`.`clients_id` AND `v2`.`date` > FROM_UNIXTIME(UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 MONTH))) 
GROUP BY `clients`.`id` 

的問題是,這兩個連接在同一個表拼成訪問雙號。

我還能做什麼?

回答

2

重複計數可能會解決你的問題

SELECT clients.*, salesagents.name, COUNT(DISTINCT v1.id) as visits_number, COUNT(DISTINCT v2.id) as visits_number_last_month 
FROM `clients` 
LEFT JOIN `salesagents` ON `clients`.`salesagents_id`=`salesagents`.`id` 
LEFT JOIN `visits` as `v1` ON `clients`.`id` = `v1`.`clients_id` 
LEFT JOIN `visits` as `v2` ON `clients`.`id` = `v2`.`clients_id` AND `v2`.`date` > FROM_UNIXTIME(UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 MONTH))) 
GROUP BY `clients`.`id` 
+0

太棒了!這麼簡單,這解決了我的問題!非常感謝! – user3514092

1

嘗試使用SUMCASE WHEN。第一個COUNT統計所有訪問者,第二個表達式僅統計訪問者是否符合日期條件。因此,在使用的CASE WHEN表達加1,如果條件適合:

SELECT 
     clients.* 
    , salesagents.name, COUNT(v1.id) as visits_number 
    , SUM(
      CASE WHEN `v1`.`date` > FROM_UNIXTIME(UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 MONTH))) 
       THEN 1 
       ELSE 0 
     END) as visits_number_last_month 
FROM `clients` 
LEFT JOIN `salesagents` ON `clients`.`salesagents_id`=`salesagents`.`id` 
LEFT JOIN `visits` as `v1` ON `clients`.`id` = `v1`.`clients_id` 
GROUP BY `clients`.`id` 
1
select c1.*, s1.name, v1.visits1, v2.visits2 
from clients c1 
left join salesagents s1 
    on c1.salesagents_id = s1.id 
left join 
    (select clients_id, count(distinct id) as visits1 
    from visits 
    group by clients_id) v1 
    on v1.clients_id = c1.id 
left join 
    (select vx.clients_id, count(distinct vx.id) as visits2 
    from visits vx 
    where vx.date >FROM_UNIXTIME(UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 MONTH))) 
    group by vx.clients_id) v2 
    on v2.clients_id = c1.id 
+0

任何解釋這樣做呢? – rbr94

+0

@ rbr94完成每個子查詢中的聚合(使用不同的)。這不是最高效的,但可以防止分組的問題 – JohnHC