[英]Transforming rows into columns with Analytic functions in Oracle's SQL
我有下表
日期 | 价格 | 顾客 | 产品 |
---|---|---|---|
2020 | 100 | 1 | 一个 |
2021 | 100 | 1 | 一个 |
2022 | 110 | 1 | 一个 |
2020 | 50 | 2 | 乙 |
2021 | 80 | 2 | 乙 |
我想转换我的数据以连续查看客户在今年(即 2022 年)和去年(即 2021 年)支付的价格,并计算其增量。 如果客户在 2022 年没有交易,我想将他们排除在我的 output 之外。
所以结果应该是这样的:
CY | 价格_CY | PY | 价格_PY | 顾客 | 产品 | 价格_Delta |
---|---|---|---|---|---|---|
2022 | 110 | 2021 | 100 | 1 | 一个 | 1.1 |
我想我需要自行加入并使用 window function,但不知道如何处理它?
您可以将LAG
function 与CTE
一起使用,如下所示:
With CTE As
(
Select Date_ As CY, Price As Price_CY,
Lag(Date_) Over (Partition By Customer, Product Order By Date_) As PY,
Lag(Price) Over (Partition By Customer, Product Order By Date_) As Price_PY,
Customer, Product,
Price / Lag(Price) Over (Partition By Customer, Product Order By Date_) As Price_Delta
From Your_Table
)
Select CY, Price_CY, PY, Price_PY, Customer, Product, Price_Delta
From CTE
Where CY = 2022 And Customer = 1 And Product = 'A'
查看来自uk<>fiddle的演示。
您可以将条件聚合与ROW_NUMBER()
分析 function 一起使用,同时将"Date"
列值与过去两年的值匹配,例如
WITH t2 AS
(
SELECT column_value AS year,
MAX(CASE WHEN "Date"=column_value THEN price END) AS price,
Customer,Product,
ROW_NUMBER()
OVER (PARTITION BY Customer,Product ORDER BY column_value DESC) AS rn
FROM table(sys.odcinumberlist(TO_CHAR(sysdate,'yyyy')-1,TO_CHAR(sysdate,'yyyy')))
CROSS JOIN t
GROUP BY column_value, Customer,Product
)
SELECT MAX(CASE WHEN rn = 1 THEN year END) AS cy,
MAX(CASE WHEN rn = 1 THEN price END) AS price_cy,
MAX(CASE WHEN rn = 2 THEN year END) AS py,
MAX(CASE WHEN rn = 2 THEN price END) AS price_py,
Customer,Product,
MAX(CASE WHEN rn = 1 THEN price END)/
MAX(CASE WHEN rn = 2 THEN price END) AS price_delta
FROM t2
GROUP BY Customer,Product
HAVING NVL(MAX(CASE WHEN rn = 1 THEN price END),0)*
NVL(MAX(CASE WHEN rn = 2 THEN price END),0)>0
如果您想要相对于当前日期的当前年份和上一年(不是每个输入年份),那么您可以按两年过滤输入,然后 pivot 它:
select cy, cy_price, py, py_price, cy_price/py_price as delta, customer_id, product from ( select * from test_tab --reduce input where dt in ( extract(year from sysdate), extract(year from sysdate) - 1 ) ) pivot( max(price) as price, max(dt) for dt in ( 2022 as cy, 2021 as py ) ) where cy is not null --there's something for this year
CY CY_PRICE PY PY_PRICE 三角洲 客户ID 产品 2022 110 2021 100 1.1 1 一个
db<> 在这里摆弄
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.