Как я могу отображать среднее в конце результатов - PullRequest
0 голосов
/ 30 сентября 2019

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

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

with a1 as (
  (
    SELECT 
      brand, 
      round(AVG(Price), 2) avg_jan,
      0 as avg_feb, 0 as avg_march, 0 as avg_april, 0 as avg_may,
      0 as avg_june, 0 as avg_july, 0 as avg_aug
    FROM (
      SELECT 
        item, 
        SUM(price) Price, 
        count(DISTINCT(item) cnt, 
        brand
      FROM myTable 
      GROUP BY item, brand
    )
    GROUP BY brand
  )
),

...
select a1.brand, a1.avg_jan,...
from a1 
left join a2 on a1.brand = a2.brand

, как это должно выглядеть

бренда |avg_jan |avg_feb |...

X ... ...

Y ... ...

всего ... ...

Ответы [ 3 ]

0 голосов
/ 30 сентября 2019

Это немного глупо, но как насчет добавления UNION в конце:

with a1 as (
  ...
),
...
-- Get detailed rows (original query)
select a1.brand, a1.avg_jan,...
from a1 
left join a2 on a1.brand = a2.brand

union all

-- Get one additional summary row
select 'total', avg(a1.avg_jan), avg(a2.avg_feb)...
from a1 
left join a2 on a1.brand = a2.brand

Обновление
Предполагается, что в вашем поле purchase_date естьВ таблице также приведены месячные средние цены по брендам:

SELECT 
  brand,
  AVERAGE(CASE WHEN EXTRACT(MONTH FROM purchase_date) = 1 THEN price END) AS avg_jan,
  AVERAGE(CASE WHEN EXTRACT(MONTH FROM purchase_date) = 2 THEN price END) AS avg_feb,
  ...
  AVERAGE(CASE WHEN EXTRACT(MONTH FROM purchase_date) = 12 THEN price END) AS avg_dec
FROM MyTable
GROUP BY brand

UNION ALL

SELECT 
  'Total',
  AVERAGE(CASE WHEN EXTRACT(MONTH FROM purchase_date) = 1 THEN price END),
  AVERAGE(CASE WHEN EXTRACT(MONTH FROM purchase_date) = 2 THEN price END),
  ...
  AVERAGE(CASE WHEN EXTRACT(MONTH FROM purchase_date) = 12 THEN price END)
FROM MyTable

Если посмотреть на исходный запрос, как вы используете item и cnt?

Для total строка, я предполагаю, что вы хотите получить общее среднее значение, а не «среднее значение среднего». Например, бренд X продает 1000 товаров по средней цене 10 долларов, а бренд Y продает 100 товаров по средней цене 20 долларов, общая средняя сумма составит: ( ($10 * 1000) + ($20 * 100) ) / (1000 + 100) = $10.91.

0 голосов
/ 03 октября 2019

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

WITH avg_sales AS
(
  SELECT *
  FROM (SELECT brand, to_char(purchase_date, 'MM') AS MONTH, price
        FROM myTable)
  PIVOT (AVG(price) AS AVG FOR MONTH IN ('01' AS JAN, '02' AS FEB, '03' AS MAR, '04' AS APR,
                                         '05' AS MAY, '06' AS JUN, '07' AS JUL, '08' AS AUG,
                                         '09' AS SEP, '10' AS OCT, '11' AS NOV, '12' AS DEC))
)
SELECT *
FROM avg_sales
UNION ALL
SELECT 'Total', 
       avg(jan_avg), avg(feb_avg), avg(mar_avg), avg(apr_avg),
       avg(may_avg), avg(jun_avg), avg(jul_avg), avg(aug_avg),
       avg(sep_avg), avg(oct_avg), avg(nov_avg), avg(dec_avg)
FROM avg_sales;

Это будет агрегировать за несколько лет, как написано сейчас, но выможно ограничить результаты с помощью BETWEEN в предложении WHERE самого внутреннего запроса или чего-то подобного.

Кроме того, если вы используете ROLLUP, будет работать следующий запрос:

SELECT DECODE(GROUPING(brand), 1, 'Total', brand) AS BRAND, 
       AVG(JAN_AVG) AS JAN_AVG, AVG(FEB_AVG) AS FEB_AVG, AVG(MAR_AVG) AS MAR_AVG, AVG(APR_AVG) AS APR_AVG,
       AVG(MAY_AVG) AS MAY_AVG, AVG(JUN_AVG) AS JUN_AVG, AVG(JUL_AVG) AS JUL_AVG, AVG(AUG_AVG) AS AUG_AVG,
       AVG(SEP_AVG) AS SEP_AVG, AVG(OCT_AVG) AS OCT_AVG, AVG(NOV_AVG) AS NOV_AVG, AVG(DEC_AVG) AS DEC_AVG
FROM (SELECT brand, to_char(purchase_date, 'MM') AS MONTH, price
      FROM myTable)
PIVOT (AVG(price) AS AVG FOR MONTH IN ('01' AS JAN, '02' AS FEB, '03' AS MAR, '04' AS APR,
                                       '05' AS MAY, '06' AS JUN, '07' AS JUL, '08' AS AUG,
                                       '09' AS SEP, '10' AS OCT, '11' AS NOV, '12' AS DEC))
GROUP BY ROLLUP(brand)
ORDER BY GROUPING(brand), brand;
0 голосов
/ 30 сентября 2019

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

SELECT item, SUM(price) Price, 
  count(DISTINCT(item) cnt,
  brand
 FROM myTable group by item, brand)
group by ROLLUP(brand);
...