【问题标题】:SQL Server - resetting a running totalSQL Server - 重置运行总计
【发布时间】:2015-10-08 22:40:12
【问题描述】:

我正在尝试导出分页逻辑。

我有这样的字段:

RecordNo  Lines 

1          20
2          130
3          50
4          60
5          350
6          100

假设我的页面大小是 170 行。

我想要得到的结果是:

RecordNo Lines CumSum PageNo

1         20   20      1
2         130  150     1
3         50   50      2   (as cumulative sum 200 exceeds 170, reset to 0)
4         60   110     2
5         350  350     3   ((as cumulative sum 460 exceeds 170, reset to 0)
6         100  100     4   ((as cumulative sum 460 exceeds 170, reset to 0)

我可以使用游标来实现,但有没有办法仅通过 SQL 来实现?

这是 OP 发布的 ddl 和示例数据:

CREATE TABLE PAGING (RECORDNO INT, LINES INT ); 
INSERT INTO PAGING VALUES(1,20); 
INSERT INTO PAGING VALUES(2,130); 
INSERT INTO PAGING VALUES(3,50); 
INSERT INTO PAGING VALUES(4,60); 
INSERT INTO PAGING VALUES(5,350); 
INSERT INTO PAGING VALUES(6,100); 

更新:

Zohar,感谢您对此进行调查。该查询与我提供的数据完美配合,但是当我使用更多数据进行扩展时,它没有给出正确的结果,因为页面库不会移动,总和超过 170。

这是我尝试使用 SQL 的数据:

INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (1, 20);    
INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (2, 130);    
INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (3, 50);    
INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (4, 60);    
INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (5, 350);    
INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (6, 100);    
INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (7, 20);    
INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (8, 10);    
INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (9, 20);    
INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (10, 30);   
INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (11, 5);    
INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (12, 5);    
INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (13, 5);    
INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (14, 10);    
INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (15, 205);    
INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (16, 156);    
INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (17, 5);    
INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (18, 2);   
INSERT [dbo].[PAGING] ([RECORDNO], [LINES]) VALUES (19, 7);

【问题讨论】:

  • 你使用的是什么版本的sql server?你能发布 ddl 和示例数据吗?
  • 我正在使用 SQL Server 2014。示例数据在第一部分。这是一个两列的表 RecordNo 和 Lines,我想要实现的结果在第二部分
  • 通过示例数据,我的意思是我可以用它来创建我的查询。当然我可以花时间把它放在一起,但我们都是这里的志愿者,如果你做腿部工作会简单得多。 :) 由于您使用的是 2014,因此您可以利用 LAG 函数创建一个运行总计,然后在总计超过 170 时增加一个页面计数器。
  • 对不起,这个论坛的新手,不知道所有的规则。这是 ddl 和插入(甚至不确定如何放置新行,因为输入帖子主题) CREATE TABLE PAGING (RECORDNO INT, LINES INT);插入分页值(1,20);插入分页值(2,130);插入分页值(3,50);插入分页值(4,60);插入分页值(5,350);插入分页值(6,100);记录将被处理 ORDER BY RECORDNO
  • 我曾考虑过 LAG 和 LEAD,但我很难了解如何重置运行总计

标签: sql-server


【解决方案1】:

更新:
这是完整的解决方案and it's fiddle link

WITH cte AS
(
    SELECT RECORDNO, 
           LINES, 
           SUM(LINES) OVER (ORDER BY RECORDNO) CumSum,
           SUM(LINES) OVER (ORDER BY RECORDNO) / 170 AS PageNumberBase
    FROM PAGING
)

SELECT RECORDNO, 
       LINES, 
       SUM(LINES) OVER (PARTITION BY PageNumberBase ORDER BY RECORDNO) As CumSum,
       DENSE_RANK() OVER(ORDER BY PageNumberBase) As PageNumber
FROM cte
ORDER BY RECORDNO

第一版:

使用 dense_rank 窗口函数和 cte 我能够产生非常接近的结果,只是 cumSum 并不完美。
不幸的是,我没有更多时间玩它,所以我将把它留在这里,并附上 sqlFiddle 的链接,并希望 OP 或其他人能够完成解决方案:

WITH cte AS
(
    SELECT RECORDNO, 
           LINES, 
           SUM(LINES) OVER (ORDER BY RECORDNO) CumSum,
           SUM(LINES) OVER (ORDER BY RECORDNO) / 170 AS PageNumber
    FROM PAGING
)

SELECT RECORDNO, 
       LINES, 
       PageNumber,
       CumSum - (170 * PageNumber) As CumSum,
       DENSE_RANK() OVER(ORDER BY PageNumber)
FROM cte

Here is the link to the fiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-25
    • 2018-01-14
    • 2018-08-22
    • 2010-10-26
    • 2021-03-27
    • 1970-01-01
    相关资源
    最近更新 更多