SQL: как выбрать оконные функции вместе с агрегатными функциями

Мне интересно, как смешать выбор столбцов, агрегированные значения, а также "выбор из разделов". Пожалуйста, дайте мне знать, если это дублирующий вопрос!

Пример того, что я имею в виду:

Приведенный пример журнала транзакций:

ID     Food    Date     Cost
1      Apple   5/1/14   10
1      Apple   5/4/14   8
1      Apple   5/6/14   15
1      Pear    5/2/14   25
2      Apple   5/3/14   15

Цель состоит в том, чтобы выбрать для каждой уникальной комбинации ID/Food, стоимость первой покупки (по дате), последней покупки, а также среднюю стоимость.

Вывод будет выглядеть так:

ID   Food    First_Cost    Last_Cost     Avg_Cost
1    Apple   10            15            11
1    Pear    25            25            25
2    Apple   15            15            15

Я рассмотрел OVER - PARTITION ( выбрать первую строку в каждой группе GROUP BY?), А также группировку рядом с агрегатными функциями ( https://dba.stackexchange.com/questions/41494/select-first-row-grouping-add-aggregate-function), но ни один, казалось, не ответил на этот конкретный вопрос.

Это пример кода того, что я пытаюсь выполнить:

select id
      ,food
      ,firstrow(cost) OVER(PARTITION BY id, food ORDER BY date asc as first_cost
      ,avg(cost) from table
group by id, food;

С использованием ROWNUMBER() OVER(PARTITION...)и затем фильтрация с предложением where тоже не работает, так как агрегатные функции были бы отключены.

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

РЕДАКТИРОВАТЬ: Из комментария jpw, Астер имеет оконную функцию first_value(). Однако проблема заключается в том, что столбцы, которые я упорядочиваю или разделяю, должны быть включены в предложение groupby. Его предложение и одно решение могли бы состоять в том, чтобы преобразовать все агрегатные функции в оконные функции и полностью исключить группу.

Хотелось бы увидеть более чистое решение или подтверждение того, что это невозможно!

2 ответа

Запрос:

select id
      ,food
      ,first_value(cost) OVER(PARTITION BY id, food ORDER BY exp_date asc) as first_cost
      ,first_value(cost) OVER(PARTITION BY id, food ORDER BY exp_date desc) as last_cost
      ,avg(cost) OVER(PARTITION BY id, food ORDER BY exp_date asc) as avg_cost
from sm_fruits

приближает вас

    id  Food    first_cost  last_cost   avg_cost
1   1   Apple   10          15          11.00
2   1   Apple   10          15          11.00
3   1   Apple   10          15          11.00
4   1   Pear    25          25          25.00
5   2   Apple   15          15          15.00

Вы можете перекрестно применить таблицу к себе (дважды), чтобы получить максимальную / минимальную дату и стоимость предмета на эту дату.

Читайте на кресте примените его ужин полезным

 select id
      ,food
      ,LastCost
      ,FirstCost
      ,avg(cost) from TABLE t1
       Cross APPLY(
                    SELECT MAX(date), cost AS LastCost FROM TABLE t2 WHERE t2.food = t1.food
                  ) maxdate
       Cross APPLY(
                    SELECT MIN(date), cost AS FirstCost FROM TABLE t3 WHERE t3.food = t1.food
                  ) mindate
group by id, food;
Другие вопросы по тегам