Sql-Server

如何根據行數和可調的批量大小將 GUID 分配給批量數據

  • March 2, 2021

我需要為成批的行分配一個通用的 GUID id(供外部程序使用)。

下面是一個簡化的設置,描述了我正在尋找的內容:

BASE_TABLE表示此方案中的一個預先存在的表,顯然已大大簡化。“真實”表中的值應該被認為是隨機的;它們在現實生活中不是連續的(即使 ID 也不是真正的 int)

CREATE TABLE BASE_TABLE (
   ID int
   ,VALUE1 varchar(10)
   ,VALUE2 varchar(255)
) 

TARGET_TABLE``uniqueIdentifier代表我正在處理的過程的“輸出”,它只是需要批量數據為每個批次都有一個 BATCHID 的其他東西的輸入。現實生活中的批次約為 1000 行。

CREATE TABLE TARGET_TABLE 
(
 ID int
 ,VALUE1 varchar(10)
 ,VALUE2 varchar(255)
 ,BATCHID uniqueIdentifier
)

(添加一些虛擬數據)

DECLARE @DATA1 int
set @DATA1=0
WHILE @DATA1<100
BEGIN
 INSERT INTO BASE_TABLE (ID,VALUE1,VALUE2) VALUES (@DATA1,'v1'+CONVERT(varchar,@DATA1), 'v2'+CONVERT(varchar,@DATA1))
 SET @DATA1=@DATA1+1
END

/** 範例 DESIRED RESULT,批量大小為 5

ETC

重要的結果是,對於每個大小為 N 的批次,有 N 行具有相同的 BatchID,它必須是一個 GUID。

我很確定我可以用游標做我想做的事,但如果可能的話,我想做這樣的事情:

select 
ID,VALUE1,VALUE2,
NEWID() OVER(PARTITION BY ROW_NUMBER() OVER (ORDER BY ID)) AS BatchID
from BASE_TABLE

但它無效,因為 NEWID() 不是聚合函式。

你必須玩 row_numbers

declare @part int = 3

;with baseRowNums as 
 (
   SELECT ID, VALUE1, VALUE2,
      Row_Number() Over (ORDER BY ID) AS rn
   FROM BASE_TABLE
 )
,batchNums as
(
SELECT *,
   Sum(CASE WHEN rn % @part = 1 THEN 1 ELSE 0 END)
   Over (ORDER BY ID, rn 
         ROWS Unbounded Preceding) AS part
FROM baseRowNums
)
,GUIDs as
(select part, MAX(newid()) as GUID
 from batchNums
 group by part
)
select ID, VALUE1, VALUE2, GUIDs.GUID
from batchNums
join GUIDs on batchNums.part = GUIDs.part

https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=7c26d9bab095ce9d8ca1abf1f4c1a898

引用自:https://dba.stackexchange.com/questions/286308