Sql 聚合函数,用于按顺序获取两行的差值或比率
我有一张满是价格、项目和日期的桌子。这方面的一个例子是:Sql 聚合函数,用于按顺序获取两行的差值或比率,sql,postgresql,aggregate-functions,greatest-n-per-group,window-functions,Sql,Postgresql,Aggregate Functions,Greatest N Per Group,Window Functions,我有一张满是价格、项目和日期的桌子。这方面的一个例子是: AA, 1/2/3024, 1.22 AA, 1/3/3024, 1.23 BB, 1/2/3024, 4.22 BB, 1/3/3024, 4.23 在数据中,每个价格只有两行,它们是按日期排序的。如何将此数据集压缩为一个产品行,显示上一个价格与上一个价格的差异?[这也适用于比率,因此AA将产生1.23/1.22] 结果应该是这样的 AA, todays price-yesterdays price 尽管是求和函数,但列表上没有减法
AA, 1/2/3024, 1.22
AA, 1/3/3024, 1.23
BB, 1/2/3024, 4.22
BB, 1/3/3024, 4.23
在数据中,每个价格只有两行,它们是按日期排序的。如何将此数据集压缩为一个产品行,显示上一个价格与上一个价格的差异?[这也适用于比率,因此AA将产生1.23/1.22]
结果应该是这样的
AA, todays price-yesterdays price
尽管是求和函数,但列表上没有减法函数
我使用的是postgres 9.1。如果每个项目只有两行,那么
SELECT item, MAX(price) - MIN(price) AS diff, MAX(price) / MIN(price) AS ratio
FROM yourtable
GROUP BY item
就可以了。如果每个项目只有两行,那么
SELECT item, MAX(price) - MIN(price) AS diff, MAX(price) / MIN(price) AS ratio
FROM yourtable
GROUP BY item
select product,
sales_date,
current_price - prev_price as diff
from (
select product,
sales_date,
price as current_price,
lag(price) over (partition by product order by sales_date) as prev_price,
row_number() over (partition by product order by sales_date desc) as rn
from the_unknown_table
) t
where rn = 1;
我会成功的
select product,
sales_date,
current_price - prev_price as diff
from (
select product,
sales_date,
price as current_price,
lag(price) over (partition by product order by sales_date) as prev_price,
row_number() over (partition by product order by sales_date desc) as rn
from the_unknown_table
) t
where rn = 1;
SQLFiddle示例:
SQLFiddle示例:因为每个价格只有两行,所以这可以更简单、更快:
SELECT n.item, n.price - o.price AS diff, n.price / o.price AS ratio
FROM price n -- "new"
JOIN price o USING (item) -- "old"
WHERE n.day > o.day;
此表单还有一个额外的好处,即您可以直接使用两行中的所有列
对于更复杂的场景(这不是必需的),您可以使用已经指出的窗口函数。这里有一个比建议的更简单的方法:
SELECT DISTINCT ON (item)
item
,price - lead(price) OVER (PARTITION BY item ORDER BY day DESC) AS diff
FROM price
ORDER BY item, day DESC;
这里只需要一个窗口函数。和一个查询级别,因为在窗口函数之后应用。窗口中的排序顺序与总体排序顺序一致,有助于提高性能。由于每个价格只有两行,因此这可以更简单、更快:
SELECT n.item, n.price - o.price AS diff, n.price / o.price AS ratio
FROM price n -- "new"
JOIN price o USING (item) -- "old"
WHERE n.day > o.day;
此表单还有一个额外的好处,即您可以直接使用两行中的所有列
对于更复杂的场景(这不是必需的),您可以使用已经指出的窗口函数。这里有一个比建议的更简单的方法:
SELECT DISTINCT ON (item)
item
,price - lead(price) OVER (PARTITION BY item ORDER BY day DESC) AS diff
FROM price
ORDER BY item, day DESC;
这里只需要一个窗口函数。和一个查询级别,因为在窗口函数之后应用。窗口中的排序顺序与总体排序顺序一致,有助于提高性能。这不起作用,因为差异必须基于日期。又名今天的价格-昨天的价格。这不起作用,因为差异必须基于日期。又名今天的价格-昨天的价格。我花了一段时间才明白需要什么行号,但现在我明白了第三条评论。。但是使用order by和order by desc是相当聪明的。起初我认为这是一个错误。我花了一些时间才理解需要什么行号,但现在我明白了第三条注释。。但是使用orderby和orderbydesc是相当聪明的。起初我认为这是一个错误。