Агрегатные функции возвращают неправильные значения при объединении нескольких таблиц - PullRequest
1 голос
/ 26 июля 2010

Я хочу отобразить всех клиентов и их адреса, а также количество и общую сумму их заказов.Мой запрос выглядит следующим образом:

select *, sum(o.tota), count(o.total) 
from customer c 
natural join orders o
group by c.custId;

, который отлично работает.

, но если я добавлю новую таблицу к запросу:

select *, sum(o.tota), count(o.total) 
from customer c 
natural join orders o
natural join cust_addresses a
group by c.custId;

, то он не будетработать больше.агрегатные функции возвращают неправильные значения, потому что может быть несколько адресов на одного клиента, и это правильно, я также хочу отобразить все их адреса.Что я могу сделать, чтобы решить проблему с агрегатной функцией?

Я мог бы подумать о том, чтобы сделать что-то вроде:

select *, (select total from orders o where o.custid=c.custid), ..
from customer c 
natural join orders o
natural join cust_addresses a
group by c.custId;

Но это очень медленно.

РЕДАКТИРОВАТЬ Теперь я попробовал следующее, но оно говорит мне, что поле c.custid неизвестно:

select *
from
     customer c,               
     left join (select sum(o.tota), count(o.total) from orders o where o.custid=c.custid) as o
where ...
group by c.custId;

Ответы [ 2 ]

4 голосов
/ 26 июля 2010

Простое решение: используйте два запроса.

В противном случае вы можете выполнить агрегированные вычисления в подзапросе (по всей таблице, а не по строке), а затем СОЕДИНИТЬ результат подзапроса с таблицей адресов, чтобы получить дополнительные данные. Попробуйте это:

SELECT *
FROM customer T1
LEFT JOIN
(
    SELECT custId,
           SUM(total) AS sum_total,
           COUNT(total) AS count_total
    FROM orders
    -- WHERE ...
    GROUP BY custId
) T2
ON T1.custId = T2.custId
-- WHERE ...
0 голосов
/ 26 июля 2010

Попробуйте что-то вроде:

select c.custId, max(c.custName) custName, ...
       a.addrId, max(a.addrLine1) addrLine1, ...
       sum(o.total) order_total, count(o.total) order_count
from customer c 
left join orders o on c.custId = o.custId
left join cust_addresses a on c.custId = a.custId
group by c.custId, a.addrId;

при условии, что вам нужны все клиенты, независимо от того, есть ли у них заказы или адреса.

...