Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 连续顺序tsql_Sql Server_Tsql_Contiguous - Fatal编程技术网

Sql server 连续顺序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

我正在寻找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
    ( 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应该在另一个组中。因此,查询需要能够处理数据,以便动态决定组。如果一行数据不能进入一个组,那么它必须是一个新组。如果行可以归入现有组,则可以将其添加到该组中。基本上,我正在处理的真实数据比我在这里提供的数据要多得多。谢谢你的帮助。