Это даст вам результаты, которые вы ищете для данных, которые мы имеем:
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
(и, следовательно, не являются расходуемыми). Я приложил усилия к исходным данным, но я не повторил процесс для новых данных.