Sql server 连续顺序tsql
我正在寻找tsql中的连续算法。我的数据设置如下所示Sql server 连续顺序tsql,sql-server,tsql,contiguous,Sql Server,Tsql,Contiguous,我正在寻找tsql中的连续算法。我的数据设置如下所示 IF OBJECT_ID('Tempdb..#Area_Version') IS NOT NULL DROP TABLE #Area_Version CREATE TABLE #Area_Version ( AreaVersionId INT , AreaId VARCHAR(1) , VersionId VARCHAR(2) , PocketGroupId INT ) INSERT INTO #Area_Version
IF OBJECT_ID('Tempdb..#Area_Version') IS NOT NULL
DROP TABLE #Area_Version
CREATE TABLE #Area_Version
(
AreaVersionId INT ,
AreaId VARCHAR(1) ,
VersionId VARCHAR(2) ,
PocketGroupId INT
)
INSERT INTO #Area_Version
( AreaVersionId, AreaId, VersionId, PocketGroupId )
VALUES ( 1, 'A', 'V5', 0 ),
( 2, 'B', 'V2', 0 ),
( 3, 'C', 'V2', 0 ),
( 4, 'D', 'V3', 0 ),
( 5, 'E', 'V2', 0 ),
( 6, 'F', 'V1', 0 ),
( 7, 'F', 'V4', 0 ),
( 8, 'G', 'V3', 0 );
结果:
AreaVersionId AreaId VersionId PocketGroupId
------------- ------ --------- -------------
1 A V5 0
2 B V2 0
3 C V2 0
4 D V3 0
5 E V2 0
6 F V1 0
7 F V4 0
8 G V3 0
(8 row(s) affected)
下面是数据的可视化表示
AreaId V1 V2 V3 V4 V5
A x
B x
C x
D x
E x
F x x
G x
按区域ID排序,我正在查找连续组。
由于V2跨越B、C和E区域,因此V2和V3在D中不能是一个连续的顺序。
上述数据集可分为两组。V5、V2、V1和V3、V4或V5、V3、V4和V2、V1。我可以根据超出问题范围的数量列来决定哪个集合优先
根据算法的结果集,我将更新PocketGroupId,以便根据PocketGroupId进行查询,我将知道它是一个连续的组
期望的结果应该是这样的
AreaVersionId AreaId VersionId PocketGroupId
------------- ------ --------- -------------
1 A V5 1
2 B V2 1
3 C V2 1
4 D V3 2
5 E V2 1
6 F V1 1
7 F V4 3
8 G V3 2
任何关于如何实现这一目标的想法。提前感谢。这是一个使用光标和while循环的动态版本。。。还有额外的临时桌。这很恶心,但很管用
IF OBJECT_ID('Tempdb..#Area_Version') IS NOT NULL
DROP TABLE #Area_Version
CREATE TABLE #Area_Version
(
AreaVersionId INT ,
AreaId VARCHAR(1) ,
VersionId VARCHAR(2) ,
PocketGroupId INT
)
INSERT INTO #Area_Version
( AreaVersionId, AreaId, VersionId, PocketGroupId )
VALUES ( 1, 'A', 'V5', 0 ),
( 2, 'B', 'V2', 0 ),
( 3, 'C', 'V2', 0 ),
( 4, 'D', 'V3', 0 ),
( 5, 'E', 'V2', 0 ),
( 6, 'F', 'V1', 0 ),
( 7, 'F', 'V4', 0 );
WITH cte
AS ( SELECT AVLeft.AreaVersionId AS [LEFT] ,
AVLeft.AreaId ,
AVLeft.VersionId ,
AVLeft.PocketGroupId ,
COALESCE(MAX(AVRight.VersionId),
( SELECT MIN(AV.VersionId)
FROM #Area_Version AS AV
)) AS maxVersion ,
COALESCE(MIN(AVRight.VersionId),
( SELECT MAX(AV.VersionId)
FROM #Area_Version AS AV
)) AS minVersion
FROM #Area_Version AS AVLeft
LEFT JOIN #Area_Version AS AVRight ON AVLeft.AreaVersionId > AVRight.AreaVersionId
GROUP BY AVLeft.AreaVersionId ,
AVLeft.AreaId ,
AVLeft.VersionId ,
AVLeft.PocketGroupId
)
SELECT cte.[LEFT] ,
cte.AreaId ,
cte.VersionId ,
CASE WHEN cte.VersionId > cte.minVersion
AND cte.VersionId < cte.maxVersion THEN 2
ELSE 1
END AS PocketGroupId
FROM cte
IF OBJECT_ID('Tempdb..#Area_Version') IS NOT NULL
DROP TABLE #Area_Version
CREATE TABLE #Area_Version
(
AreaVersionId INT ,
AreaId VARCHAR(1) ,
VersionId VARCHAR(2) ,
PocketGroupId INT
)
INSERT INTO #Area_Version (AreaVersionId, AreaId, VersionId, PocketGroupId) VALUES (1, 'A', 'V5', 0)
INSERT INTO #Area_Version (AreaVersionId, AreaId, VersionId, PocketGroupId) VALUES (2, 'B', 'V2', 0)
INSERT INTO #Area_Version (AreaVersionId, AreaId, VersionId, PocketGroupId) VALUES (3, 'C', 'V2', 0)
INSERT INTO #Area_Version (AreaVersionId, AreaId, VersionId, PocketGroupId) VALUES (4, 'D', 'V3', 0)
INSERT INTO #Area_Version (AreaVersionId, AreaId, VersionId, PocketGroupId) VALUES (5, 'E', 'V2', 0)
INSERT INTO #Area_Version (AreaVersionId, AreaId, VersionId, PocketGroupId) VALUES (6, 'F', 'V1', 0)
INSERT INTO #Area_Version (AreaVersionId, AreaId, VersionId, PocketGroupId) VALUES (7, 'F', 'V4', 0)
INSERT INTO #Area_Version (AreaVersionId, AreaId, VersionId, PocketGroupId) VALUES (8, 'G', 'V2', 0)
INSERT INTO #Area_Version (AreaVersionId, AreaId, VersionId, PocketGroupId) VALUES (9, 'H', 'V4', 0)
IF OBJECT_ID('Tempdb..#WorkingArea_Version') IS NOT NULL
DROP TABLE #WorkingArea_Version
CREATE TABLE #WorkingArea_Version
(
AreaVersionId INT ,
AreaId VARCHAR(1) ,
VersionId VARCHAR(2) ,
PocketGroupId INT
)
INSERT INTO #WorkingArea_Version
SELECT * FROM #Area_Version
IF OBJECT_ID('Tempdb..#resultset') IS NOT NULL
DROP TABLE #resultset
CREATE TABLE #resultset
(
PocketGroupId INT ,
VersionId NVARCHAR(MAX)
)
DECLARE @areaCount INT
SELECT @areaCount = COUNT(1)
FROM #WorkingArea_Version av
DECLARE @PocketGroupId INT
SET @PocketGroupId = 1
WHILE ( @areaCount > 0 )
BEGIN
DECLARE @AreaVersionId INT ,
@AreaId VARCHAR(1) ,
@VersionId VARCHAR(2)
DECLARE db_cursor CURSOR
FOR
SELECT av.AreaVersionId ,
av.AreaId ,
av.VersionId
FROM #WorkingArea_Version av
ORDER BY av.AreaId
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @AreaVersionId, @AreaId, @VersionId
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @Versions NVARCHAR(MAX) = ''
IF NOT EXISTS ( SELECT TOP 1
1
FROM #resultset r
WHERE r.PocketGroupId = @PocketGroupId )
BEGIN
INSERT INTO #resultset
( PocketGroupId, VersionId )
VALUES ( @PocketGroupId, @VersionId )
END
ELSE
BEGIN
DECLARE @minAreaId NVARCHAR(1)
DECLARE @maxAreaId NVARCHAR(1)
--current max
SELECT @maxAreaId = MAX(AreaId)
FROM #resultset r
JOIN #WorkingArea_Version av ON av.VersionId = r.VersionId
--potentials min
SELECT @minAreaId = MIN(AreaId)
FROM #WorkingArea_Version av
WHERE av.VersionId = @VersionId
IF ( @minAreaId > @maxAreaId )
BEGIN
INSERT INTO #resultset
( PocketGroupId, VersionId )
VALUES ( @PocketGroupId, -- PocketGroupId - int
@VersionId -- VersionId - nvarchar(max)
)
END
END
FETCH NEXT FROM db_cursor INTO @AreaVersionId, @AreaId,
@VersionId
END
CLOSE db_cursor
DEALLOCATE db_cursor
DELETE FROM #WorkingArea_Version
WHERE VersionId IN ( SELECT r.VersionId
FROM #resultset r )
SELECT @areaCount = COUNT(1)
FROM #WorkingArea_Version av
SET @PocketGroupId = @PocketGroupId + 1
END
SELECT av.AreaVersionId, av.AreaId, av.VersionId, r.PocketGroupId
FROM #Area_Version av
JOIN #resultset r ON r.VersionId = av.VersionId
ORDER BY av.AreaVersionId
哪个版本的sql server?谢谢。如果我有2个以上,如何更动态地执行此操作PocketGroups@SK,请提供一个示例,如您的问题中的视觉表示我已更新了问题中数据的视觉表示。现在V3应该单独在一个组中,V4应该在另一个组中。因此,查询需要能够处理数据,以便动态决定组。如果一行数据不能进入一个组,那么它必须是一个新组。如果行可以归入现有组,则可以将其添加到该组中。基本上,我正在处理的真实数据比我在这里提供的数据要多得多。谢谢你的帮助。