给行组一个数值,然后为每一个下一组递增

时间:2018-11-01 16:09:40

标签: tsql sql-server-2017

我已使用此脚本创建了一个表:

CREATE TABLE [dbo].[BatchTest](
    [Col1] [varchar](50) NULL,
    [Col2] [varchar](50) NULL,
    [Col3] [varchar](50) NULL,
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [BatchId] [int] NOT NULL,
 CONSTRAINT [PK_BatchTest] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

我一直想知道CTE是否可以用来实现这一目标: 将第一组记录的BatchId列的值设置为固定值,然后对于每个下一组记录,BatchId的值应为:prev。组的号码+ 1 ..等等

group by子句:Col1,Col2,Col3

结果:

A   B   C   34
A   B   C   34
A   B   C   34
A   B   C   34

A   B   D   35
A   B   D   35
A   B   D   35
A   B   D   35

A   B   E   36
A   B   E   36
A   B   E   36
A   B   E   36

开始编号。在这种情况下为34。依此类推,增加下一组记录。用户输入的开始号码。

预先感谢!

2 个答案:

答案 0 :(得分:2)

我不确定我是否了解购买问题,我认为您正在寻找dense_rank

样本数据:

INSERT INTO BatchTest (Col1, Col2, Col3, BatchId) VALUES
('1', '1', '1', 0),
('1', '1', '2', 0),
('1', '1', '3', 0),
('1', '1', '1', 0),
('1', '1', '2', 0),
('1', '1', '3', 0);

查询:

SELECT Col1, Col2, Col3, BatchId, Id, DENSE_RANK() OVER(ORDER BY Col1, Col2, Col3) As DR
FROM BatchTest
ORDER BY DR

结果:

Col1    Col2    Col3    BatchId Id  DR
1       1       1       0       1   1
1       1       1       0       4   1
1       1       2       0       5   2
1       1       2       0       2   2
1       1       3       0       3   3
1       1       3       0       6   3

答案 1 :(得分:1)

如果用户指定了开头的BatchId,则可以使用变量来修改DENSE_RANK()函数的值。使用您的数据集(略微随机以显示INSERT INTO BatchTest ( Col1 ,Col2 ,Col3 ,BatchId ) VALUES ('A','B','C',0), ('A','B','C',0), ('A','B','E',0), ('A','B','C',0), ('A','B','D',0), ('A','B','D',0), ('A','B','D',0), ('A','B','C',0), ('A','B','E',0), ('A','B','E',0), ('A','B','D',0), ('A','B','E',0) 正常工作),我插入了以下内容:

UPDATE

然后,您可以使用变量作为BatchId的起始值,并将Zohar的最终查询修改为JOIN,就像这样,使用CTE生成BatchId值,然后DECLARE @BatchId INT = 34 ;WITH BatchedIds AS ( SELECT ID , Col1 , Col2 , Col3 , BatchId = ( DENSE_RANK() OVER ( ORDER BY Col1, Col2, Col3 )) + @BatchId - 1 FROM BatchTest ) UPDATE bt SET bt.BatchId = bi.BatchId FROM BatchTest bt INNER JOIN BatchedIds bi ON bi.ID = bt.ID 将CTE更改为BatchTest:

SELECT * FROM BatchTest
ORDER BY BatchId

ID  Col1    Col2    Col3    BatchId
4   A       B       C       34
1   A       B       C       34
2   A       B       C       34
8   A       B       C       34
5   A       B       D       35
6   A       B       D       35
7   A       B       D       35
11  A       B       D       35
12  A       B       E       36
9   A       B       E       36
10  A       B       E       36
3   A       B       E       36

然后,您可以查询BatchTest并获得以下结果:

DetailView