表上每 N 条记录增加列值

Posted

技术标签:

【中文标题】表上每 N 条记录增加列值【英文标题】:Increment value on column every N records on table 【发布时间】:2014-03-14 19:54:38 【问题描述】:

我需要在表列上每 4 条记录增加 +1,我尝试使用 ROW_NUM() 但我的肮脏解决方法没有意义。

这是我需要的:

Index PeriodID
1       1
1       2
1       3
1       4
2       5
2       6
2       7
2       8

PeriodID 是表“Periods”的主键(聚集索引),我听说过窗口函数 LAG() 和 LEAD() 但不确定我是否可以将这个概念应用于这种情况,以下语法是我的失败的恶作剧尝试:

选择 row_number() over (order by periodid)/4+1, 周期 从句号

我得到的结果:

Index PeriodID
1       1
1       2
1       3
2       4
2       5
2       6
2       7
3       8

我明白为什么会得到这个结果,但我想知道是否有内置的 T-SQL 函数可以帮助实现我的需要。

欢迎提出意见和建议

谢谢

【问题讨论】:

NTILE 几乎可以做到这一点,但对于不均匀的组,它会平衡它们,而不是在最后一组中留下尽可能小的数字。 【参考方案1】:

我不太熟悉解决这类问题的内置函数,但你可以用简单的数学来解决(我相信有人可以加强这一点,只是第一次通过):

CREATE TABLE #t (PeriodID int PRIMARY KEY, ExpectedIndex int);
INSERT INTO #t VALUES (1, 1),(2, 1),(3, 1),(4, 1),(5, 2),(6, 2),(7, 2),(8, 2),(9, 3),(10, 3),(11, 3),(13, 3);

SELECT ((RowNum - ((RowNum - 1) % 4)) / 4) + 1 AS [Index], ExpectedIndex, PeriodID
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY PeriodID) AS RowNum, ExpectedIndex, PeriodID FROM #t
    ) AS tSub1

DROP TABLE #t;

编辑:我很好奇,这是一个 LAG 版本(同样,毫无疑问没有优化),加上子查询只是为了展示我的工作:

SELECT
    (RowNum - IncrementalLag) / 4 AS ZeroBasedIndex
    ,((RowNum - IncrementalLag) / 4) + 1 AS [Index]
    ,ExpectedIndex
    ,PeriodID
FROM
    (
    SELECT 
        RowNum
        ,LAG(RowNum,1,0) OVER (ORDER BY RowNum) % 4 AS IncrementalLag
        ,ExpectedIndex
        ,PeriodID
    FROM (
        SELECT ROW_NUMBER() OVER (ORDER BY PeriodID) AS RowNum, ExpectedIndex, PeriodID FROM #t
        ) AS tSub1
    ) AS tSub2;

【讨论】:

我的直觉是“普通数学”可能是最好的答案。我认为您不需要 CONVERT(INT,...)。我喜欢您将您期望的结果构建到您的示例数据中。【参考方案2】:

我相信@downwitch 是对的,是一个简单的数学问题,但我相信我有一个可能的答案:

select (row_number() over (order by primaryKeyColumnName) -1)/N from table

其中 N 是创建新分区的记录数

希望这个答案对其他人也有效

【讨论】:

这几乎就是你的“肮脏把戏”的更正版本。为您的计算添加一个 +1,它成为所需的 1 基数。 这是更好的简单数学。

以上是关于表上每 N 条记录增加列值的主要内容,如果未能解决你的问题,请参考以下文章

为每个提取的记录在其他表上计算聚合 - 性能

Pyspark - 如何检查两条记录中哪一条具有最新日期及其列值?

查询性能问题 - 对于 select 语句,即使表上有超过 20 万亿条记录的索引

是否可以将 SELECT 语句中具有重复列值的记录与 SQL 中的另一条记录合并?

从具有重复列值的集合中选择第一条记录 C#

如何根据单个表中的两个列值获取 1 条记录?