2015-08-03 6 views
0

Я начинающий в MySQL. Я пытаюсь запросить некоторые данные из базы данных телефонной карты voip, для которой мне необходимо присоединиться к нескольким таблицам. Это давало правильный результат, пока не было две таблицы левого соединения, но когда я добавил третью таблицу, столбец «общая продолжительность» дает неверный вывод.MySQL multiple Left Join получает неправильный вывод

Мой первый запрос выглядел так, и выход был в этом 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 

ответ

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 
+0

Спасибо Мелани, я пробовал это, но не улучшился, можем ли мы думать о другом? – Hayan

0



ничего себе, я не уверен, как это работает, но я только что удалил left join и попробовал, какой выход правильное значение, как и ожидалось,

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

 
\t from clientsshared as c 
 

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

 
\t where c.id_reseller='10' 
 

 
\t group by c.id_client 
 

 
\t order by total_duration desc

0

При объединении таблиц создает кратное числа строк

Например, если есть 2 вызова в среднем в таблице вызовов для каждого клиента, тогда вы получаете 2x количество клиентских строк, а затем, если на среднем клиенте 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