【问题标题】:Give group of rows a numeric value and increment for every next group给一组行一个数值并为每个下一组递增
【发布时间】:2018-11-01 16:09:39
【问题描述】:

我用这个脚本创建了一个表:

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.. 以此类推

按子句分组: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。依此类推,为下一组记录增加它。起始编号由用户输入。

提前致谢!

【问题讨论】:

  • 这听起来像是一个 X Y 问题。 xyproblem.info你到底想做什么?
  • 另外,向我们展示 DDL 表是提出问题的良好第一步,但我们需要查看实际使用该表的代码才能为您提供帮助。
  • 好吧,我尝试了一些查询,但不值得在描述中添加,因为它们没有给出接近我想要达到的结果。

标签: tsql sql-server-2017


【解决方案1】:

我不确定我是否理解购买我认为您正在寻找的问题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

【讨论】:

  • 谢谢!我确实想到了 DENSE_RANK() 但是它不允许为第一组确定的起始编号选择起始编号,然后为每个下一组增加编号。此外,BatchId 列是需要更新的列。
【解决方案2】:

如果起始BatchId是用户指定的,可以使用变量来修改DENSE_RANK()函数的值。使用您的数据集,稍微随机显示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)

然后您可以使用一个变量作为 BatchId 起始值并将 Zohar 的最终查询修改为 UPDATE,就像这样,使用 CTE 生成 BatchId 值,然后 JOINing CTE 到 BatchTest:

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

然后你可以查询 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

【讨论】:

  • 哦,我的错!错过了变量 -1 的技巧。谢谢@digital.aaron!这对我有帮助。
猜你喜欢
  • 2018-03-03
  • 1970-01-01
  • 2021-07-22
  • 2018-12-20
  • 1970-01-01
  • 2012-02-09
  • 1970-01-01
  • 2019-06-28
  • 2021-08-21
相关资源
最近更新 更多