我正在尝试设计一种方法,该方法始终累加A列(单位),有时累加B列(价格),具体取决于C列(版本)的值,同时向上滚动到D列(产品)级别。我正在考虑使用case when语句,但是我遇到的问题是围绕对Price的依赖,Price具有某种分层系统。我必须在可用的情况下获取当前版本的价格值,然后在可用的情况下获取最新版本的价格值,然后,如果当前和最近的版本都不可用,则需要获取旧版本的价格值。层列表为当前>最近>旧。现在,数据在SQL Server中。
要增加另一个折痕,如果同一产品对于两个较高版本的层具有不同的价格,则返回的价格应与最旧版本的价格不同。例如,如果同一产品的三行的价格分别为50、50和10,以及版本分别为“旧”,“最近”和“最近”,则返回的价格将为10。
因此,如果起始数据如下所示:
--------------------------------------------------
| Units | Price | Version | Product |
--------------------------------------------------
| 105 | 50 | Old | Bear |
--------------------------------------------------
| 100 | 100 | Recent | Bear |
--------------------------------------------------
| 100 | 150 | Current | Bear |
--------------------------------------------------
| 97 | 50 | Old | Bear |
--------------------------------------------------
| 67 | 50 | Old | Goose |
--------------------------------------------------
| 28 | 50 | Recent | Goose |
--------------------------------------------------
| 10 | 10 | Recent | Goose |
--------------------------------------------------
数据的汇总版本如下所示:
--------------------------------------------------
| Units | Price | Version | Product |
--------------------------------------------------
| 402 | 150 | Current | Bear |
--------------------------------------------------
| 105 | 10 | Recent | Goose |
--------------------------------------------------
我是SQL新手,所以很抱歉,如果这是一个菜鸟问题。非常感谢您提供的帮助。
答案 0 :(得分:1)
另一种选择是将WITH TIES子句与Row_Number()配合使用
示例
Select Top 1 with ties
Units = sum(Units) over (Partition By Product)
,Price
,Version
,Product
From YourTable
Order By Row_Number() over (Partition By Product Order by case when Version='Old' then 3 when Version='Recent' then 2 else 1 end)
返回
Units Price Version Product
402 150 Current Bear
95 10 Recent Goose
编辑-请求的更新
在这里,我们使用CTE中的lag()函数确定价格的变化
Declare @YourTable Table ([Units] int,[Price] int,[Version] varchar(50),[Product] varchar(50))
Insert Into @YourTable Values
(105,50,'Old','Bear')
,(100,100,'Recent','Bear')
,(100,150,'Current','Bear')
,(97,50,'Old','Bear')
,(67,50,'Old','Goose')
,(28,50,'Recent','Goose')
,(10,10,'Recent','Goose')
;with cte as (
Select Units = sum(Units) over (Partition By Product)
,Price
,Version
,Product
,PrevPrice = abs(Price-lag(Price,1) over (Partition By Product Order by case when Version='Old' then 3 when Version='Recent' then 2 else 1 end desc) )
From @YourTable
)
Select top 1 with ties
Units
,Price
,Version
,Product
From cte
Order By Row_Number() over (Partition By Product Order by case when Version='Old' then 3 when Version='Recent' then 2 else 1 end ,PrevPrice desc)
返回
Units Price Version Product
402 150 Current Bear
105 10 Recent Goose
答案 1 :(得分:0)
您可以使用条件聚合。诀窍是按您的优先顺序。一种方法使用row_number()
和case
:
select sum(units) as units,
max(case when seqnum = 1 then price end) as price,
max(case when seqnum = 1 then version end) as version,
product
from (select t.*,
row_number() over (partition by product
order by (case version when 'old' then 3 when 'recent' then 2 when 'current' then 1 else 4 end)
) as seqnum
from t
) t
group by product;