3

我想知道如何混合选择列、聚合值以及'selects-from-partitions'。如果这是一个重复的问题,请告诉我!

我的意思的一个例子:

给定示例事务日志:

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/食物组合选择第一次购买的成本(按日期)、最后一次购买以及平均成本。

输出如下所示:

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...)and then 过滤 where 子句似乎也不起作用,因为聚合函数将关闭。

一种解决方案可能总是创建一个表,其中包含第一个、一个与最后一个、一个与平均值并将三个连接在一起,但我正在寻找更清洁的东西。

编辑:根据 jpw 的评论,Aster 确实具有 first_value() 窗口函数。但是,它的问题是我排序或分区的列必须包含在 groupby 子句中。他的建议和一种解决方案可能是将所有聚合函数更改为窗口函数并完全消除 groupby。

仍然希望看到更清洁的解决方案或确认这是不可能的!

4

2 回答 2

0

询问:

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
于 2016-04-11T23:21:50.157 回答
-2

您可以将表格交叉应用到其自身(两次)以获得最大/最小日期和该日期的项目成本。

在十字架上阅读 应用它的晚餐很有用

 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;
于 2015-02-25T21:15:18.380 回答