Дайте группе строк числовое значение и приращение для каждой следующей группы - PullRequest
0 голосов
/ 01 ноября 2018

Я создал таблицу с помощью этого скрипта:

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 должно быть: пред. номер группы + 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 в этом случае. и так далее увеличивать его для следующей группы записей. start no вводится пользователем.

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

Если начальный 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 и затем JOIN, используя 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
0 голосов
/ 01 ноября 2018

Я не совсем уверен, что понимаю вопрос о покупке. Думаю, вы ищете 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
...