发现产品价格异常
Finding anomalies in the product prices
我遇到了一个 SQL 问题,这个问题让我很困惑,我想知道是否有人可以阐明执行此操作的最佳方法。
问题:
鉴于 table “product_price” 表示一段时间内产品的平均价格。该范围内的所有日期都出现在未排序的“天”列中。
day
Price ($)
4
2
5
1
3
1
1
1
2
5
查找该时间段内产品价格的异常情况,更具体地说,查找价格飙升的日子(价格严格高于前一天和后一天的日子)。
第一天和最后一天永远不会是峰值。
预期结果:输出应按“天”升序排列
day
2
4
查询:我已经厌倦了这个查询
SELECT day FROM (
SELECT
day
,prev_price - price AS pre_diff
,price - next_price AS next_diff
FROM (
SELECT
day
,price
,LEAD(price) OVER(price) AS prev_price
,LAG(price) OVER(price) AS next_price
FROM product_price
ORDER BY day ASC
) a
) b
WHERE pre_diff > 1 and next_diff > 1
ORDER by day;
更新: 我想我已经解决了。感谢@hsnsd 的提示。如果有更好的方法来编写此查询,我们仍将不胜感激。
SELECT day FROM (
SELECT
day
,price
,prev_price
,next_price
,price - prev_price AS pre_diff
,next_price - price AS next_diff
FROM (
SELECT
day
,price
,COALESCE(LAG(price) OVER(ORDER BY day ASC),0) AS prev_price
,COALESCE(LEAD(price) OVER(ORDER BY day ASC),0) AS next_price
FROM prices
) a
) b
WHERE (day NOT IN (SELECT MIN(day) FROM prices) AND
day NOT IN (SELECT MAX(day) FROM prices))
AND (pre_diff > 0 AND next_diff < 0)
ORDER BY "day";
看起来下面应该会给你想要的结果:
with s as (
select *,
Lag(Price, 1, Price) over(order by day) p,
Lead(Price, 1, Price) over(order by day) n
from prices
)
select day
from s
where p < Price and n < Price;
我遇到了一个 SQL 问题,这个问题让我很困惑,我想知道是否有人可以阐明执行此操作的最佳方法。
问题: 鉴于 table “product_price” 表示一段时间内产品的平均价格。该范围内的所有日期都出现在未排序的“天”列中。
day | Price ($) |
---|---|
4 | 2 |
5 | 1 |
3 | 1 |
1 | 1 |
2 | 5 |
查找该时间段内产品价格的异常情况,更具体地说,查找价格飙升的日子(价格严格高于前一天和后一天的日子)。
第一天和最后一天永远不会是峰值。
预期结果:输出应按“天”升序排列
day |
---|
2 |
4 |
查询:我已经厌倦了这个查询
SELECT day FROM (
SELECT
day
,prev_price - price AS pre_diff
,price - next_price AS next_diff
FROM (
SELECT
day
,price
,LEAD(price) OVER(price) AS prev_price
,LAG(price) OVER(price) AS next_price
FROM product_price
ORDER BY day ASC
) a
) b
WHERE pre_diff > 1 and next_diff > 1
ORDER by day;
更新: 我想我已经解决了。感谢@hsnsd 的提示。如果有更好的方法来编写此查询,我们仍将不胜感激。
SELECT day FROM (
SELECT
day
,price
,prev_price
,next_price
,price - prev_price AS pre_diff
,next_price - price AS next_diff
FROM (
SELECT
day
,price
,COALESCE(LAG(price) OVER(ORDER BY day ASC),0) AS prev_price
,COALESCE(LEAD(price) OVER(ORDER BY day ASC),0) AS next_price
FROM prices
) a
) b
WHERE (day NOT IN (SELECT MIN(day) FROM prices) AND
day NOT IN (SELECT MAX(day) FROM prices))
AND (pre_diff > 0 AND next_diff < 0)
ORDER BY "day";
看起来下面应该会给你想要的结果:
with s as (
select *,
Lag(Price, 1, Price) over(order by day) p,
Lead(Price, 1, Price) over(order by day) n
from prices
)
select day
from s
where p < Price and n < Price;