在不破坏序列的情况下对列进行分组

Grouping Column Without Breaking The Sequence

主要objective是将Amount列之后的行按顺序分组,这样,如果2个相同的值之间有任何不同的值,它们将被编号分别地。 这是这里的原始数据:

SELECT Area, DateA, DateB, Amount
FROM (VALUES
    ('ABC', '2019-08-18', '2019-08-18 00:07:47.000', 3.75),
    ('ABC','2019-08-19', '2019-08-19 00:08:47.000', 3.75),
    ('ABC','2019-08-20', '2019-08-20 00:09:47.000', 3.65),
    ('ABC','2019-08-21', '2019-08-21 00:09:57.000', 3.75))
    AS FeeCollection(Area, DateA, DateB, Amount)

我已经试过了,但是我不知道以特殊方式编号的真正问题。

DENSE_RANK() OVER(ORDER BY Area, Amount)

这是我想要达到的示例结果。我正在寻找简单的逻辑来做到这一点。使用游标或 while 循环对我来说效率不高。

我相信这就是你想要的。我使用 LAG 获取 CTE 中前一行的值,然后使用窗口 COUNT 将具有相同连续值的每一行的 ROW_NUMBER 的值减少 1 amount:

WITH CTE AS(
    SELECT Area,
           DateA,
           DateB,
           Amount,
           LAG(Amount) OVER (PARTITION BY Area ORDER BY DateA) AS PrevAmount
    FROM (VALUES
        ('ABC', '2019-08-18', '2019-08-18 00:07:47.000', 3.75),
        ('ABC','2019-08-19', '2019-08-19 00:08:47.000', 3.75),
        ('ABC','2019-08-20', '2019-08-20 00:09:47.000', 3.65),
        ('ABC','2019-08-21', '2019-08-21 00:09:57.000', 3.75))
        AS FeeCollection(Area, DateA, DateB, Amount))
SELECT Area,
       DateA,
       DateB,
       Amount,
       ROW_NUMBER() OVER (PARTITION BY Area ORDER BY DateA) - 
       COUNT(CASE Amount WHEN PrevAmount THEN 1 END) OVER (PARTITION BY Area ORDER BY DateA
                                                           ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Number
FROM CTE
ORDER BY DateA;

我确实假定了您的 PARTITION BY 子句,您可能需要 change/remove/move 到 ORDER BY。由于我们只有一个 Area 的值,因此无法知道它更改时该值应该是什么。

我会使用 lag() 和累计总和来执行此操作,但看起来像:

select t.*,
       sum(case when prev_amount = amount then 0 else 1 end) over
           (partition by area order by datea) as number
from (select t.*,
             lag(amount) over (partition by area order by datea) as prev_amount
      from t
     ) t;