2016-07-11 4 views
1

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

  • ПРОДУКТЫ: prod_id: целое число, цена: десятичные
  • OrderLines: prod_id: целое число, количество: целое

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

select avg(sum) as avg_sales 
from (
    select sum(b.quantity * a.price) as total_sales 
    from products a, orderlines b 
    where a.prod_id = b.prod_id 
    group by a.prod_id 
); 

Когда я пытаюсь это, я получаю:

ERROR: subquery in FROM must have an alias.

Я не понимаю этого, но я новичок в Postgres. Во всяком случае, добавление псевдонима дает мне:

select avg(totals) as avg_sales 
from (
    select sum(b.quantity * a.price) as total_sales 
    from products a, orderlines b 
    where a.prod_id = b.prod_id group by a.prod_id 
) as totals; 

Когда я пытаюсь это, я получаю: Ошибка: функция ср (запись) не существует

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

+0

Я думаю [этот вопрос] (http://stackoverflow.com/questions/38237244/how-do-calculate-the-average-when-the-numbers-are-grouped) поможет вы.Как я думаю, я спросил то же самое, что и вы. – MageeWorld

+0

«Все, что я пытаюсь вернуть синтаксическую ошибку», основополагающий смысл, чтобы опубликовать точную ошибку – e4c5

+0

Это помогает (я стараюсь быть более полезным и менее грубым, поскольку большинство пользователей, похоже, для новичков), чтобы выписать код, который работает , Если вы ищете более высокие, чем средние продажи в долларах, некоторые имена столбцов отсутствуют. Кроме того, как вы определяете свою среднюю продажу в долларах? – MageeWorld

ответ

0

Вы можете попробовать что-то вроде этого. Во-первых, используя вспомогательный запрос найти средние продажи, а затем получить все продукты выше, что продажи

SELECT p.prod_id, o.quantity 
    FROM products p INNER JOIN orderlines o 
    ON p.prod_id = o.prod_id 
    WHERE o.quantity > (  SELECT AVG(ol.quantity) 
           FROM products pr INNER JOIN orderlines ol 
           ON pr.prod_id = ol.prod_id 
         ) 
+0

Решена ли ваша проблема? –

+0

Ошибка при получении: ERROR: более чем одна строка, возвращаемая подзапросом, используемым в качестве выражения. Ваш подзапрос возвращает каждый продукт и его среднее значение. – 1earldog

+0

О, извините, вам нужно удалить эту группу по заявлению, и если вы попробуете после этого, то она должна работать. Я думаю, –

1

When I try this, I get: ERROR: function avg(record) does not exist

Это потому, что вы передаете псевдоним производной таблицы функции avg(), что означает, что вы передаете полная строка (= запись), а не один столбец (значение).

Чтобы получить, что работать вам нужно использовать:

select avg(totals.total_sales) as avg_sales 
from (
    select sum(ol.quantity * p.price) as total_sales 
    from products p 
     join orderlines ol on p.prod_id = ol.prod_id 
    group by p.prod_id 
) as totals; 

Обратите внимание, что я заменил древний, устаревшие и хрупкая неявное присоединиться современной явной JOIN оператора. Если вы изучаете SQL, вы должны привыкнуть к этому синтаксису.


Чтобы получить продукты с выше, чем в среднем продажи, вам нужно вычислить как: продажи за продукт и средняя продажи.

Это может быть достигнуто путем использования a window function в то время как агрегирование:

select p.prod_id, 
     sum(ol.quantity * p.price) as total_sales, 
     avg(sum(ol.quantity * p.price)) over() as average_sales 
from products p 
    join orderlines ol on p.prod_id = ol.prod_id 
group by p.prod_id; 

Это может теперь быть завернуты в производной таблице, чтобы отфильтровать те, с более низким общего объема продаж:

select * 
from (
    select p.prod_id, 
     sum(ol.quantity * p.price) as total_sales, 
     avg(sum(ol.quantity * p.price)) over() as average_sales 
    from products p 
    join orderlines ol on p.prod_id = ol.prod_id 
    group by p.prod_id 
) t 
where total_sales >= average_sales; 

SQLFiddle например: http://sqlfiddle.com/#!15/7f8ab/1

+0

Большое спасибо за ваше решение и объяснение. Это решает мою проблему. Кстати, мне вдруг стало неожиданно утром, что, если мы получим общий средний объем продаж, основанный на общем объеме продаж каждого продукта, то по определению половина продуктов будет иметь более чем средний объем продаж, поэтому, возможно, все, что мне нужно было сделать занимал первое место по объемам продаж и занимал первые 50%. – 1earldog

Смежные вопросы