MySQL多个Left Join输出错误

时间:2015-08-03 11:09:37

标签: mysql

我是MySQL的初学者。我试图从voip电话卡数据库中查询一些我需要加入多个表的数据。它提供了正确的输出,直到有两个左连接表,但是当我添加第三个表然后"总持续时间"列输出错误。

我的第一个查询看起来像这样,输出就在这个screencap enter image description here

select c.login,cname.Name,cname.LastName,DATE_FORMAT(Creation_Date,'%d-%m-%y')as regdate,DATE_FORMAT((Select max(call_start) from calls where calls.id_client = c.id_client),'%d-%m-%y') as lastcall, c.account_state,sum(cdr.duration / 60) as total_duration from clientsshared as c
left join invoiceclients as cname on cname.IdClient = c.id_client
left join calls as cdr on cdr.id_client = c.id_client
where c.id_reseller='10' group by c.id_client order by total_duration desc limit 100

新查询就是这样,输出错误,请查看screencap enter image description here

select c.login,cname.Name,cname.LastName,DATE_FORMAT(Creation_Date,'%m-%d-%y')as regdate, 
(Select max(data) from payments where payments.id_client = c.id_client) as lastpayment,
(Select max(call_start) from calls where calls.id_client = c.id_client) as lastcall, 
c.account_state,sum(cdr.duration / 60) as total_duration from clientsshared as c

left join invoiceclients as cname on cname.IdClient = c.id_client
left join payments as p on p.id_client = c.id_client
left join calls as cdr on cdr.id_client = c.id_client
where c.id_reseller='10' group by c.id_client order by total_duration desc limit 100

3 个答案:

答案 0 :(得分:0)

select c.login,cname.Name,cname.LastName,DATE_FORMAT(Creation_Date,'%m-%d-%y')as regdate, 
(Select max(data) from payments where payments.id_client = c.id_client) as lastpayment,
(Select max(call_start) from calls where calls.id_client = c.id_client) as lastcall, 
c.account_state,sum(cdr.duration / 60) as total_duration 

from clientsshared as c

left join invoiceclients as cname on cname.IdClient = c.id_client
left join calls as cdr on cdr.id_client = c.id_client
left join payments as p on p.id_client = cdr.id_client

where c.id_reseller='10' 

group by c.id_client 

order by total_duration desc limit 100

答案 1 :(得分:0)



哇,我不知道它是如何工作的但我只是删除了一个left join并尝试输出正确的值,如预期的那样,

    select c.login,cname.Name,cname.LastName,cname.Creation_Date as regdate, 
	(Select max(data) from payments where payments.id_client = c.id_client) as lastpayment,
	(Select max(call_start) from calls where calls.id_client = c.id_client) as lastcall, 
	c.account_state,sum(cdr.duration / 60) as total_duration 

	from clientsshared as c

	left join invoiceclients as cname on cname.IdClient = c.id_client
	left join calls as cdr on cdr.id_client = c.id_client

	where c.id_reseller='10' 

	group by c.id_client 

	order by total_duration desc

答案 2 :(得分:0)

当您连接表时,它会创建行数的倍数

例如,如果每个客户端的呼叫表中平均有2个呼叫,那么您获得客户端行数的2倍,那么如果每个客户端平均有3个付款,则客户端数量是3倍(2x)。这种乘数效应在进行聚合时可能会导致错误。为避免此问题,可能需要在作为子查询加入之前进行分组。

请试试这个:

SELECT c.LOGIN
 ,cname.NAME
 ,cname.LastName
 ,DATE_FORMAT(Creation_Date, '%d-%m-%y') AS regdate
 ,p.lastpayment
 ,DATE_FORMAT(max(cdr.call_start), '%d-%m-%y') AS lastcall
 ,c.account_state
 ,sum(cdr.duration / 60) AS total_duration
FROM clientsshared AS c
LEFT JOIN invoiceclients AS cname ON cname.IdClient = c.id_client
LEFT JOIN calls AS cdr ON cdr.id_client = c.id_client
LEFT JOIN (
 SELECT id_client
  ,max(data) AS lastpayment
 FROM payments
 GROUP BY id_client
 ) p ON p.id_client = c.id_client
WHERE c.id_reseller = '10'
GROUP BY c.id_client
ORDER BY total_duration DESC limit 100

请注意您已加入电话表,因此不需要执行此操作“相关子查询”

 ,DATE_FORMAT((
   SELECT max(call_start)
   FROM calls
   WHERE calls.id_client = c.id_client
   ), '%d-%m-%y') AS lastcall

而你需要的只是:

 ,DATE_FORMAT(max(cdr.call_start), '%d-%m-%y') AS lastcall