谢谢你的关注。 我有一个名为“PROD_COST”的表,有5个字段
(ID,Duration,Cost,COST_NEXT,COST_CHANGE).
我需要额外的字段称为“组”进行聚合。
现在我需要按Cost_change进行分组。有可能 正,负或0值。
+----+---+------+------+------+
| 1 | 1 | 10 | 8,5 | -1,5 |
| 2 | 1 | 8,5 | 12,2 | 3,7 |
| 3 | 1 | 12,2 | 5,3 | -6,9 |
| 4 | 1 | 5,3 | 4,2 | 1,2 |
| 5 | 1 | 4,2 | 6,2 | 2 |
| 6 | 1 | 6,2 | 9,2 | 3 |
| 7 | 1 | 9,2 | 7,5 | -2,7 |
| 8 | 1 | 7,5 | 6,2 | -1,3 |
| 9 | 1 | 6,2 | 6,3 | 0,1 |
| 10 | 1 | 6,3 | 7,2 | 0,9 |
| 11 | 1 | 7,2 | 7,5 | 0,3 |
| 12 | 1 | 7,5 | 0 | 7,5 |
+----+---+------+------+------+`
我需要进行查询,该查询将按照第一个负值或正值(+ - + - + - )对其进行分组。最后一个字段是我想要的。 对不起我的英文`
+----+---+------+------+------+---+
| 1 | 1 | 10 | 8,5 | -1,5 | 1 |
| 2 | 1 | 8,5 | 12,2 | 3,7 | 2 |
| 3 | 1 | 12,2 | 5,3 | -6,9 | 3 |
| 4 | 1 | 5,3 | 4,2 | 1,2 | 4 |
| 5 | 1 | 4,2 | 6,2 | 2 | 4 |
| 6 | 1 | 6,2 | 9,2 | 3 | 4 |
| 7 | 1 | 9,2 | 7,5 | -2,7 | 5 |
| 8 | 1 | 7,5 | 6,2 | -1,3 | 5 |
| 9 | 1 | 6,2 | 6,3 | 0,1 | 6 |
| 10 | 1 | 6,3 | 7,2 | 0,9 | 6 |
| 11 | 1 | 7,2 | 7,5 | 0,3 | 6 |
| 12 | 1 | 7,5 | 0 | 7,5 | 6 |
+----+---+------+------+------+---+`
答案 0 :(得分:0)
如果您在SQL Server 2012中,可以使用窗口函数执行此操作:
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)) then 1 else 0 end as GRP
from
PROD_COST
) X
Lag将从前一行获取值,检查它的符号并将其与当前行进行比较。如果值不匹配,则大小写将返回1.外部选择将执行这些数字的运行总计,并且每次有1时,它将增加总数。
也可以在旧版本中使用相同的逻辑,您只需要使用id从表中获取前一行,并通过重新计算当前行之前的所有行来执行总计。< / p>
中的示例答案 1 :(得分:0)
詹姆斯的答案很接近,但它没有正确处理零值。这是一个非常简单的修改。一个棘手的近似值使用了产品变化之间的差异:
select id, COST_CHANGE, sum(IsNewGroup) over (order by id asc) +1
from (select pc.*,
(case when sign(cost_change) - sign(lag(cost_change) over (order by id)) between -1 and 1
then 0
else 1 -- `NULL` intentionally goes here
end) IsNewGroup
from Prod_Cost
) pc
为清楚起见,here是一个零值的SQL小提琴。根据我对这个问题的理解,OP只希望实际改变符号。
这可能仍然不正确。 OP根本不清楚如何处理0值。