Группировка набора строк и присвоение / обновление уникального номера каждому набору в SQL Server - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть требование группировать n-е (настраиваемые) строки (сумки) по некоторым критериям (Zone), а затем назначать / обновлять каждую группу уникальным идентификатором, который никогда не должен повторяться для любой другой группы в этой таблице (Shipping_Bags).

В настоящее время у меня есть несколько пустых полей (UserDef1 / 2 ..) в моей таблице, где я могу обновить / заполнить значение UniqueGroupID. В настоящее время мои данные выглядят так: Пакеты, которые уже доставлены / отправлены, имеют UniqueGroupID, аналогичным образом нам необходимо обновить UniqueGroupID для будущих поставок, поэтому, отфильтровывая UniqueGroupID, система сможет найти с ним 4 связанных пакета. Отсюда требование уникальности.

Select BagId, Zone, UserDef1, ShipDate from Shipping_Bag;

BagID     Zone           UserDef1     ShipDate
1         East              1        24/04/2018
2         East              1        24/04/2018
3         East              1        24/04/2018
4         East              1        24/04/2018
5         East              2        24/04/2018
6         East              2        24/04/2018
7         East              2        24/04/2018
8         West              3        25/04/2018
9         West              3        25/04/2018
10        North             4        25/04/2018
11        North             0        27/04/2018
12        North             0        27/04/2018
13        North             0        27/04/2018
14        North             0        27/04/2018
15        Central           0        27/04/2018
16        Central           0        27/04/2018
17        Central           0        27/04/2018
18        Central           0        27/04/2018
19        Central           0        27/04/2018

Я хочу получить результат ниже (Группировка 4 мешка на Зону):

Select BagId, Zone, UserDef1 as UniqueGroupID, ShipDate from Shipping_Bag;

   BagID     Zone      UniqueGroupID     ShipDate
    1         East              1        24/04/2018
    2         East              1        24/04/2018
    3         East              1        24/04/2018
    4         East              1        24/04/2018
    5         East              2        24/04/2018
    6         East              2        24/04/2018
    7         East              2        24/04/2018
    8         West              3        25/04/2018
    9         West              3        25/04/2018
    10        North             4        25/04/2018
    11        North             5        27/04/2018
    12        North             5        27/04/2018
    13        North             5        27/04/2018
    14        North             5        27/04/2018
    15        Central           6        27/04/2018
    16        Central           6        27/04/2018
    17        Central           6        27/04/2018
    18        Central           6        27/04/2018
    19        Central           7        27/04/2018

Я попытался и получил вывод:

выберите BagID, Zone, - рассчитать номер группы для каждых 4 пакетов, с шагом 1 потолок (row_number () over (разделение по зонам по BagID) / 4.0) UniqueGroupID от shipping_bag

Вызов здесь есть; Мне нужно придумать логику NextUp Number, чтобы обновить / заполнить UniqueGroupID, чтобы он никогда не повторился ни для какого BagID в будущем.

1 Ответ

0 голосов
/ 26 апреля 2018

Это даст вам результаты, которые вы ищете для данных, которые мы имеем:

USE Sandbox;
GO

CREATE TABLE Shipping (BagID int, [Zone] varchar(5), UserDef int);

INSERT INTO Shipping
VALUES (1,'East',0),
       (2,'East',0),
       (3,'East',0),
       (4,'East',0),
       (5,'East',0),
       (6,'East',0),
       (7,'East',0),
       (8,'West',0),
       (9,'West',0),
       (10,'North',0),
       (11,'North',0),
       (12,'North',0),
       (13,'North',0),
       (14,'North',0);
GO
DECLARE @BagSize int = 4;

WITH RNs AS(
    SELECT *,
           ROW_NUMBER() OVER (ORDER BY BagID) AS RN,
           ROW_NUMBER() OVER (PARTITION BY [Zone] ORDER BY BagID) AS BagRN
    FROM Shipping)
SELECT BagID,
       [Zone],
       DENSE_RANK() OVER (ORDER BY (RN - BagRN) + ((BagRN -1) / @BagSize)) AS UniqueGroupID
FROM RNs
ORDER BY BagID;

GO
DROP TABLE Shipping;
GO

Редактировать: хорошо, возможно, это работает, что вам нужно, когда у вас уже есть данные:

USE Sandbox;
GO

CREATE TABLE Shipping (BagID int, [Zone] varchar(5), UserDef int);

INSERT INTO Shipping
VALUES (1,'East',1),
       (2,'East',1),
       (3,'East',1),
       (4,'East',1),
       (5,'East',2),
       (6,'East',2),
       (7,'East',3),
       (8,'West',4),
       (9,'West',4),
       (10,'North',0),
       (11,'North',0),
       (12,'North',0),
       (13,'North',0),
       (14,'North',0);
GO
DECLARE @BagSize int = 4;

WITH RNs AS(
    SELECT *,
           ROW_NUMBER() OVER (ORDER BY BagID) AS RN,
           ROW_NUMBER() OVER (PARTITION BY [Zone] ORDER BY BagID) AS BagRN,
           CASE UserDef WHEN 0 THEN 0 ELSE 1 END AS UserDefBit,
           MAX(UserDef) OVER () AS MaxUserDef
    FROM Shipping)
SELECT BagID,
       [Zone],
       CASE UserDef WHEN 0 THEN DENSE_RANK() OVER (PARTITION BY UserDefBit ORDER BY (RN - BagRN) + ((BagRN -1) / @BagSize)) + MaxUserDef
                    ELSE UserDef END AS UniqueGroupID
FROM RNs
ORDER BY BagID;

GO
DROP TABLE Shipping;
GO

Примечание: я не пробовал это с новыми образцами данных OP, так как они не в форме оператора INSERT (и, следовательно, не являются расходуемыми). Я приложил усилия к исходным данным, но я не повторил процесс для новых данных.

...