对A列求和,但不对B列求和,具体取决于C列-SQL Server

时间:2018-10-25 23:29:11

标签: sql sql-server

我正在尝试设计一种方法,该方法始终累加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新手,所以很抱歉,如果这是一个菜鸟问题。非常感谢您提供的帮助。

2 个答案:

答案 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;