对A列求和,而不对B列求和,具体取决于C列-SQL Server
我正试图设计一种方法,总是对a列(单位)求和,有时对B列(价格)求和,这取决于C列(版本)的值,同时滚动到D列(产品)级别。我想用一个case-when语句,但我遇到的问题是对价格的依赖,这是一种分层系统。如果可用,我必须取当前版本的价格值,如果可用,则取最近版本的价格值,如果当前版本和最近版本都不可用,我需要取旧版本的价格值。层列表变为当前>最近>旧。现在数据在SQL Server中 另外,如果同一产品的两个更高版本的价格不同,则返回的价格应不同于最旧版本的价格。例如,如果同一产品的三行价格分别为50、50和10以及旧版本、新版本和新版本,则返回的价格将为10 因此,如果起始数据如下所示:对A列求和,而不对B列求和,具体取决于C列-SQL Server,sql,sql-server,Sql,Sql Server,我正试图设计一种方法,总是对a列(单位)求和,有时对B列(价格)求和,这取决于C列(版本)的值,同时滚动到D列(产品)级别。我想用一个case-when语句,但我遇到的问题是对价格的依赖,这是一种分层系统。如果可用,我必须取当前版本的价格值,如果可用,则取最近版本的价格值,如果当前版本和最近版本都不可用,我需要取旧版本的价格值。层列表变为当前>最近>旧。现在数据在SQL Server中 另外,如果同一产品的两个更高版本的价格不同,则返回的价格应不同于最旧版本的价格。例如,如果同一产品的三行价格分
--------------------------------------------------
| 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 |
--------------------------------------------------
数据的汇总版本如下所示:
--------------------------------------------------
| 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新手,如果这是一个新手问题,我深表歉意。非常感谢您提供的任何帮助。您可以使用条件聚合。诀窍是按优先级排序。一种方法使用
行号()
和大小写
:
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;
另一个选项是将WITHTIES子句与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
Units Price Version Product
402 150 Current Bear
105 10 Recent Goose
编辑-请求的更新
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)
这里,我们使用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
95 10 Recent Goose
Units Price Version Product
402 150 Current Bear
105 10 Recent Goose
很好的回答,这完美地解决了我的示例数据。我在实际数据中发现了一个复杂问题,即有两个不同的价格值都是“当前”的,我需要选择与“最近”价格值不同的值。我如何修改代码来处理这种情况?@user3347996。我建议你接受这个问题的答案,然后再问另一个问题,以合适的数据为例。谢谢John,这非常有帮助。我有一个和戈登一样的问题:我在实际数据中发现了一个复杂问题,即有两个不同的价格值都是“当前”的,我需要选择与“最近”价格值不同的值。我如何修改代码来处理这种情况?@user3347996如果您使用新的示例数据和所需的结果更新您的问题,也许可以。我相信lag()可以解决您的问题。谢谢John。我用新的样本数据更新了问题,并根据您的建议更改了所需的结果。@user3347996请参见编辑