Агрегирование соседних строк с разбиением - PullRequest
2 голосов
/ 16 июня 2019

У меня огромный набор данных в MS SQL 2012, где необходимо выполнить специальную агрегацию. Вот пример набора данных.

Key PartitionID StartTime                   Duration    Name
1   1           23/05/2019 18:18:28.125     1           X   
2   1           23/05/2019 18:18:28.480     2           Y   
3   1           23/05/2019 18:18:29.622     1           X   
4   1           23/05/2019 18:18:32.513     2           X   
5   2           23/05/2019 18:21:13.973     3           X   
6   2           23/05/2019 18:21:14.945     4           X   
7   2           23/05/2019 18:21:21.949     5           X   
8   2           23/05/2019 18:21:30.871     2           X   
9   2           23/05/2019 18:21:35.710     4           X   
10  2           23/05/2019 18:21:48.550     1           X   
11  2           23/05/2019 18:22:00.144     3           X   
12  2           23/05/2019 18:22:01.094     6           X   
13  2           23/05/2019 18:22:03.354     1           X   
14  3           23/05/2019 18:24:44.219     6           X   
15  3           23/05/2019 18:24:46.076     1           Y   
16  3           23/05/2019 18:24:52.399     4           X   
17  3           23/05/2019 18:25:03.620     6           X   
18  3           23/05/2019 18:25:11.208     1           X   
19  3           23/05/2019 18:25:12.616     4           X   
20  3           23/05/2019 18:25:28.019     6           X   
21  3           23/05/2019 18:25:31.384     2           Y   
21  3           23/05/2019 18:25:32.334     2           Y   
21  3           23/05/2019 18:25:33.344     2           X   

Мне нужно создать новый столбец, который разбивает данные на наборы на основе имени, при этом значение параметра CalculatedID для одного и того же имени должно быть другим, если оно разделено другим именем. Другими словами, если соседние строки имеют одинаковое имя, они также имеют одинаковый CalculatedId.

Результат должен быть примерно таким:

Key PartitionID StartTime                   Duration    Name    CalculatedID
1   1           23/05/2019 18:18:28.125     1           X       1
2   1           23/05/2019 18:18:28.480     2           Y       2
3   1           23/05/2019 18:18:29.622     1           X       3
4   1           23/05/2019 18:18:32.513     2           X       3
5   2           23/05/2019 18:21:13.973     3           X       1
6   2           23/05/2019 18:21:14.945     4           X       1
7   2           23/05/2019 18:21:21.949     5           X       1
8   2           23/05/2019 18:21:30.871     2           X       1
9   2           23/05/2019 18:21:35.710     4           X       1
10  2           23/05/2019 18:21:48.550     1           X       1
11  2           23/05/2019 18:22:00.144     3           X       1
12  2           23/05/2019 18:22:01.094     6           X       1
13  2           23/05/2019 18:22:03.354     1           X       1
14  3           23/05/2019 18:24:44.219     6           X       1
15  3           23/05/2019 18:24:46.076     1           Y       2
16  3           23/05/2019 18:24:52.399     4           X       3
17  3           23/05/2019 18:25:03.620     6           X       3
18  3           23/05/2019 18:25:11.208     1           X       3
19  3           23/05/2019 18:25:12.616     4           X       3
20  3           23/05/2019 18:25:28.019     6           X       3
21  3           23/05/2019 18:25:31.384     2           Y       4
21  3           23/05/2019 18:25:32.334     2           Y       4
21  3           23/05/2019 18:25:33.344     2           X       5

Я бы действительно хотел избежать циклического перебора данных, поскольку наборы легко превышают 10 млн.

1 Ответ

3 голосов
/ 16 июня 2019

Это можно сделать, используя общее табличное выражение с lag, чтобы получить предыдущее значение для Name для каждого необработанного на основе значений PartitionId и StartTime, а затем использовать sum в качестве оконной функции для полученияСуммарная сумма строк, в которых предыдущее имя отличается от текущего имени.

Сначала создайте и заполните образец таблицы ( Пожалуйста, сохраните этот шаг в своих будущих вопросах):

DECLARE @T AS TABLE
(
    [Key] int,
    PartitionID int,
    StartTime datetime,
    Duration int,   
    Name char(1)
)

INSERT INTO @T ([Key] ,PartitionID, StartTime, Duration, Name) VALUES
(1 , 1, '2019-05-23T18:18:28.125', 1, 'X'),   
(2 , 1, '2019-05-23T18:18:28.480', 2, 'Y'),   
(3 , 1, '2019-05-23T18:18:29.622', 1, 'X'),   
(4 , 1, '2019-05-23T18:18:32.513', 2, 'X'),   
(5 , 2, '2019-05-23T18:21:13.973', 3, 'X'),   
(6 , 2, '2019-05-23T18:21:14.945', 4, 'X'),   
(7 , 2, '2019-05-23T18:21:21.949', 5, 'X'),   
(8 , 2, '2019-05-23T18:21:30.871', 2, 'X'),   
(9 , 2, '2019-05-23T18:21:35.710', 4, 'X'),   
(10, 2, '2019-05-23T18:21:48.550', 1, 'X'),   
(11, 2, '2019-05-23T18:22:00.144', 3, 'X'),   
(12, 2, '2019-05-23T18:22:01.094', 6, 'X'),   
(13, 2, '2019-05-23T18:22:03.354', 1, 'X'),   
(14, 3, '2019-05-23T18:24:44.219', 6, 'X'),   
(15, 3, '2019-05-23T18:24:46.076', 1, 'Y'),   
(16, 3, '2019-05-23T18:24:52.399', 4, 'X'),   
(17, 3, '2019-05-23T18:25:03.620', 6, 'X'),   
(18, 3, '2019-05-23T18:25:11.208', 1, 'X'),   
(19, 3, '2019-05-23T18:25:12.616', 4, 'X'),   
(20, 3, '2019-05-23T18:25:28.019', 6, 'X'),   
(21, 3, '2019-05-23T18:25:31.384', 2, 'Y'),   
(21, 3, '2019-05-23T18:25:32.334', 2, 'Y'),   
(21, 3, '2019-05-23T18:25:33.344', 2, 'X')

Общее табличное выражение:

;WITH CTE AS
(
    SELECT  [Key] ,PartitionID, StartTime, Duration, Name,
            LAG(Name) OVER(PARTITION BY PartitionID ORDER BY StartTime) As PrevName
    FROM @T
)

Запрос:

SELECT  [Key] ,PartitionID, StartTime, Duration, Name, 
        SUM(IIF(Name = PrevName, 0, 1)) OVER(PARTITION BY PartitionID ORDER BY StartTime) As CalculatedId
FROM CTE
ORDER BY [Key]

Результаты:

Key PartitionID StartTime               Duration    Name    CalculatedId
1   1           23.05.2019 18:18:28     1           X       1
2   1           23.05.2019 18:18:28     2           Y       2
3   1           23.05.2019 18:18:29     1           X       3
4   1           23.05.2019 18:18:32     2           X       3
5   2           23.05.2019 18:21:13     3           X       1
6   2           23.05.2019 18:21:14     4           X       1
7   2           23.05.2019 18:21:21     5           X       1
8   2           23.05.2019 18:21:30     2           X       1
9   2           23.05.2019 18:21:35     4           X       1
10  2           23.05.2019 18:21:48     1           X       1
11  2           23.05.2019 18:22:00     3           X       1
12  2           23.05.2019 18:22:01     6           X       1
13  2           23.05.2019 18:22:03     1           X       1
14  3           23.05.2019 18:24:44     6           X       1
15  3           23.05.2019 18:24:46     1           Y       2
16  3           23.05.2019 18:24:52     4           X       3
17  3           23.05.2019 18:25:03     6           X       3
18  3           23.05.2019 18:25:11     1           X       3
19  3           23.05.2019 18:25:12     4           X       3
20  3           23.05.2019 18:25:28     6           X       3
21  3           23.05.2019 18:25:31     2           Y       4
21  3           23.05.2019 18:25:32     2           Y       4
21  3           23.05.2019 18:25:33     2           X       5  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...