我发布了几个主题,每个查询都有一些问题:(更改了表格和示例以便更好地理解
我有一个名为PROD_COST
的表,有5个字段
(ID,Duration,Cost,COST_NEXT,COST_CHANGE).
我需要额外的字段,称为" groups"用于聚合。
示例:
+----+---------+------+-------------+-------+
|ID |Duration | Cost | Cost_change | Groups|
+----+---------+------+-------------+-------+
| 1 | 1 | 10 | -1,5 | 1 |
| 2 | 1 | 8,5 | 3,7 | 2 |
| 3 | 1 | 12.2 | 0 | 2 |
| 4 | 1 | 12.2 | -2,2 | 3 |
| 5 | 1 | 10 | 0 | 3 |
| 6 | 1 | 10 | 3.2 | 4 |
| 7 | 1 | 13.2 | -2,7 | 5 |
| 8 | 1 | 10.5 | -1,5 | 5 |
| 9 | 1 | 9 | 0 | 5 |
| 10 | 1 | 9 | 0 | 5 |
| 11 | 1 | 9 | -1 | 5 |
| 12 | 1 | 8 | 1.5 | 6 |
+----+---------+------+-------------+-------+
现在我需要通过Cost_change对(" Groups" field)进行分组。它可以是正数,负数或0值。 某种善意的人告诉我这个问题:
select id, COST_CHANGE, sum(GRP) over (order by id asc) +1
from
(
select *, case when sign(COST_CHANGE) != sign(isnull(lag(COST_CHANGE)
over (order by id asc),COST_CHANGE)) and Cost_change!=0 then 1 else 0 end as GRP
from PROD_COST
) X
但是存在一个问题:如果两个正值或负值之间的值为0,则分别对它进行分组,例如:
+-------------+--------+
| Cost_change | Groups |
+-------------+--------+
| 9.262 | 5777 |
| -9.262 | 5778 |
| 9.262 | 5779 |
| 0.000 | 5779 |
| 9.608 | 5780 |
| -11.231 | 5781 |
| 10.000 | 5782 |
+-------------+--------+
我需要:
+-------------+--------+
| Cost_change | Groups |
+-------------+--------+
| 9.262 | 5777 |
| -9.262 | 5778 |
| 9.262 | 5779 |
| 0.000 | 5779 |
| 9.608 | 5779 | -- Here
| -11.231 | 5780 |
| 10.000 | 5781 |
+-------------+--------+
换句话说,如果两个正两个负值之间的值为0,那么它们应该在一个组中,因为序列:MINUS-0-0-MINUS - 无旋转。但是如果我有MINUS-0-0-PLUS,那么GROUPS应该是1-1-1-2,因为正值正在以负值旋转。 谢谢你的关注!
我正在使用Sql Server 2012
答案 0 :(得分:0)
我认为最好的方法是删除零,进行计算,然后重新插入它们。所以:
with pcg as (
select pc.*, min(id) over (partition by grp) as grpid
from (select pc.*,
(row_number() over (order by id) -
row_number() over (partition by sign(cost_change)
order by id
) as grp
from prod_cost pc
where cost_change <> 0
) pc
)
select pc.*, max(groups) over (order by id)
from prod_cost pc left join
(select pcg.*, dense_rank() over (order by grpid) as groups
from pcg
) pc
on pc.id = pcg.id;
CTE根据组中的最低ID分配组标识符,其中组以实际符号更改为界。子查询将其转换为数字。外部查询然后累积最大值,以给0
记录赋值。