Проблема SQL с агрегатными функциями в предложении where - PullRequest
6 голосов
/ 04 ноября 2010

Я работаю над этой проблемой SQL:

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

При выполнении оператора sql я получаю следующий код:

Код ошибки -1, состояние SQL 42903: недопустимое использованиеагрегатная функция.

select 
  purchaseorder.ponum, 
  purchaseorder.amount, 
  sum(poitems.quantity*poitems.unitprice), 
  purchaseorder.amount-sum(poitems.quantity*poitems.unitprice)
from  purchaseorder, poitems
where 
  purchaseorder.ponum = poitems.ponum 
    and purchaseorder.amount!=sum(poitems.quantity*poitems.unitprice)
group by 
  purchaseorder.ponum, 
  purchaseorder.amount

Я думаю, это потому, что я использую агрегатную функцию в моем предложении where.

Как я могу решить эту проблему ???

Спасибо,

Ответы [ 4 ]

5 голосов
/ 04 ноября 2010

Попробуйте это:

select 
  purchaseorder.ponum, 
  purchaseorder.amount, 
  sum(poitems.quantity*poitems.unitprice),   
  purchaseorder.amount-sum(poitems.quantity*poitems.unitprice) 
from  purchaseorder, poitems 
where 
  purchaseorder.ponum = poitems.ponum 
group by 
  purchaseorder.ponum, 
  purchaseorder.amount 
having  
  purchaseorder.amount!=sum(poitems.quantity*poitems.unitprice)
3 голосов
/ 04 ноября 2010

Вы не можете использовать агрегат в предложении where - для этого having - измените на

select purchaseorder.ponum,
       purchaseorder.amount,
       sum(poitems.quantity*poitems.unitprice) as actual,
       purchaseorder.amount - sum(poitems.quantity*poitems.unitprice) as diff
from  purchaseorder,
      poitems
where purchaseorder.ponum = poitems.ponum
group by purchaseorder.ponum,
         purchaseorder.diff
having diff != 0
order by ABS(diff) desc
1 голос
/ 04 ноября 2010

Похоже, что вместо этого следует использовать предложение HAVING:

SELECT    ...
FROM      purchaseorder
JOIN      poitems ON (purchaseorder.ponum = poitems.ponum)
GROUP BY  purchaseorder.ponum, purchaseorder.amount
HAVING    purchaseorder.amount != sum(poitems.quantity * poitems.unitprice);

Предложение HAVING применяется почти последним и применяется в основном для фильтрации по агрегатным функциям.LIMIT применяется после HAVING.

Обратите внимание, что стандарт SQL требует, чтобы HAVING должен ссылаться только на столбцы в предложении GROUP BY или столбцы, используемые в агрегатных функциях.Однако MySQL поддерживает расширение этого поведения и позволяет HAVING ссылаться на столбцы в списке SELECT и на столбцы во внешних подзапросах.

В качестве дополнительного примечания вы также можете захотетьиспользуйте явное Inner Join (как показано в моем примере) вместо старого синтаксиса ANSI-89, который вы используете.

0 голосов
/ 04 ноября 2010

Вот что сработало для меня.Спасибо, ребята!

select purchaseorder.ponum,
   purchaseorder.amount,
   sum(poitems.quantity*poitems.unitprice) as actual,
   purchaseorder.amount - sum(poitems.quantity*poitems.unitprice) as "diff"
FROM      purchaseorder
JOIN      poitems ON (purchaseorder.ponum = poitems.ponum)
GROUP BY  purchaseorder.ponum, purchaseorder.amount
HAVING    purchaseorder.amount != sum(poitems.quantity * poitems.unitprice)
order by "diff" desc
...