2017-03-14 7 views
1

다음과 같은 간단한 테이블 구조가 있습니다. 실제로 Slot은 ID이며 테이블은 몇 줄 전에 새로 생성되므로 해당 열에 대한 간격은 없습니다. 그래서 현재의 위의 슬롯을 업데이트해야 할 지 :자체 참조 복잡한 커서를보다 효율적인 SQL 코드로 변환하는 방법? CTE, CROSS-APPLY 또는 다른 것?

Slot SlotGroup EventNum ScheduleGroup 
55  55   18   6 
56  55   19   7 
57  57   13   6 
58  57   14   7 
59  57   15   7 
60  57   15   7 
61  57   17   7 
62  57   17   7 
63  63   16   7 
64  63   16   7 
65  65   15   6 
66  65   15   6 

나는 (동일한 SlotGroup 내) 작은 슬롯을 가진 모든 레코드가 같은 ScheduleGroup하지만 서로 다른 EventNum이있는 경우 MyTable에 각 레코드 trhough 가서 확인해야 같은 SlotGroup 내에서. 결과 테이블 포함되어야하지만 다른 동일한 ScheduleGroup EventNum 갖는 이전 라인 있었다

Slot SlotGroup EventNum ScheduleGroup 
... 
59  59   15   7 
60  59   15   7 
61  61   17   7 
62  61   17   7 
... 
63  63   16   7 
64  63   16   7 
... 

SlotGroups 모두에 있기 때문이다.

CTE 또는 CROSS APPLY에 대해 생각하고 있었지만 지금은 시작하는 방법에 대한 단서가 없습니다. 올바른 솔루션을 찾는데 저를 도울 수 있습니까?

내가 사용하는 코드는 현재이지만, MyTable에는 수백 줄의 코드가있을 수 있으며,이 코드를 해결하는 가장 효율적인 방법은 아니라고 생각합니다.

데이터 :

DECLARE @MyTable TABLE (
    Slot      int --identity 
    , SlotGroup     int    NULL 
    , EventNum     int    NULL 
    , ScheduleGroup    int 
) 

INSERT INTO @MyTable VALUES(55,55,18,6) 
INSERT INTO @MyTable VALUES(56,55,19,7) 
INSERT INTO @MyTable VALUES(57,57,13,6) 
INSERT INTO @MyTable VALUES(58,57,14,7) 
INSERT INTO @MyTable VALUES(59,57,15,7) 
INSERT INTO @MyTable VALUES(60,57,15,7) 
INSERT INTO @MyTable VALUES(61,61,14,6) 
INSERT INTO @MyTable VALUES(62,61,15,7) 
INSERT INTO @MyTable VALUES(63,61,16,7) 
INSERT INTO @MyTable VALUES(64,61,16,7) 
INSERT INTO @MyTable VALUES(65,65,15,6) 
INSERT INTO @MyTable VALUES(66,65,15,6) 

번호 :

-- Go trhough each record in @MyTable and check if all records with a smaller Slot 
--(within the same SlotGroup) have have the same ScheduleGroup but different EventNum. 
-- If so do an update of the Slots above the current one (within the same SlotGroup) 
DECLARE @nStartSlot   int--Will be set later within the loop 
DECLARE @nCurScheduleGroup int 
DECLARE @nCurEventNum  int 
DECLARE @nCurSlotGroup  int 
DECLARE @nCurSlot   int 
DECLARE mtCur CURSOR FOR 
SELECT ScheduleGroup, EventNum, SlotGroup, Slot FROM @MyTable 

OPEN mtCur 
FETCH NEXT FROM mtCur INTO @nCurScheduleGroup, @nCurEventNum, @nCurSlotGroup, @nCurSlot 

WHILE @@FETCH_STATUS = 0 
BEGIN 
--Only the records with smaller Slot then the current one but within the same SlotGroup 
--are interesting. therefore get the lowest Slot from the SAME SlotGroup. 
--(important if the current records is in a new SlotGroup based on the time splitting) 
    IF NOT EXISTS (SELECT 1 
        FROM @MyTable mt 
        WHERE mt.Slot = ISNULL(@nStartSlot, 0) 
        AND mt.SlotGroup = @nCurSlotGroup 
       ) 
    BEGIN 
    SELECT @nStartSlot = MIN(Slot) 
    FROM @MyTable mt 
    WHERE mt.SlotGroup = @nCurSlotGroup 
    END 

--Update all records above the current records but within the same SlotGroup, 
--if we find a new EventNum (but ScheduleGroup) in the current SlotGroup. 
    IF EXISTS (SELECT 1 
       FROM @MyTable mt 
       WHERE mt.Slot >= @nStartSlot 
       AND mt.Slot <= @nCurSlot 
       AND mt.ScheduleGroup = @nCurScheduleGroup 
       AND mt.EventNum != @nCurEventNum 
      ) 
    BEGIN 
    UPDATE mt 
    SET SlotGroup = @nCurSlot 
    FROM @MyTable mt 
    WHERE mt.Slot >= @nCurSlot 
     AND mt.SlotGroup = @nCurSlotGroup 

    SELECT @nStartSlot = @nCurSlot 
    END 

    FETCH NEXT FROM mtCur INTO @nCurScheduleGroup, @nCurEventNum, @nCurSlotGroup, @nCurSlot 
END 
CLOSE mtCur 
DEALLOCATE mtCur 

--EDIT-- 추가 데이터 세트로 변환한다

SOURCE 1

Slot SlotGroup EventNum ScheduleGroup 
16  13   3   778 
17  17   10   778 
18  17   10   778 
19  17   9   778 
20  17   9   778 

RESULT 1

Slot SlotGroup EventNum ScheduleGroup 
... 
19  19   9   778 
20  19   9   778 

SOURCE 2

Slot SlotGroup EventNum ScheduleGroup 
39  39   10   778 
40  39   10   778 
41  39   9   778 
42  39   10   778 

RESULT 변환되어야 2

Slot SlotGroup EventNum ScheduleGroup 
39  39   10   778 
40  39   10   778 
41  41   9   778 
42  42   10   778 

--edit 2-- 가 추가 데이터 세트 이 테스트 세트가 expectedslotgroup을 내 결과와 일치하지 이상 lead()

;with cte as (
select * 
    , NewSlotGroup = min(slot) over (partition by testset, grp) 
from (
    select *, grp = sum(sgrp) over (partition by testset order by slot) 
    from (
    select *, sgrp = case 
     when lag(eventnum) over (partition by testset order by slot) = eventnum 
     then 0 
     when lag(eventnum) over (partition by testset, slotgroup order by slot) <> eventnum 
     and lag(schedulegroup) over (partition by testset, slotgroup order by slot) <> schedulegroup 
     then 0 
     else 1 
     end 
    from t 
    ) s 
) g 
) 
update cte 
    set SlotGroup = NewSlotGroup 
where SlotGroup != NewSlotGroup; 

lag() 새 테스트 세트 중 하나를 위의 코드 충돌을 사용

Slot SlotGroup EventNum ScheduleGroup ExpectedSlotGroup 
8  8   1   978    8 
9  8   2   978    9 
10  8   2   977    9 
11  8   2   977    9 
12  8   1   977    12 
13  8   2   978    12 
14  8   1   978    14 
15  8   2   978    15 
16  8   1   978    16 
Slot SlotGroup EventNum ScheduleGroup ExpectedSlotGroup 
17  17   1   331    17 
18  17   1   331    17 
19  17   1   331    17 
20  17   1   331    17 
21  17   1   331    17 
22  17   1   331    17 
23  17   1   331    17 
24  17   1   330    17 
25  17   1   330    17 
26  17   1   330    17 
27  17   1   330    17 
28  17   1   330    17 
29  17   1   330    17 
30  17   1   330    17 
31  17   2   330    31 
32  17   2   330    31 
33  17   2   330    31 
34  17   2   330    31 
35  17   2   330    31 
36  17   2   330    31 
37  17   2   330    31 
38  17   2   331    31 
39  17   2   331    31 
40  17   2   331    31 
41  17   2   331    31 
42  17   2   331    31 
43  17   2   331    31 
44  17   2   331    31 
Slot SlotGroup EventNum ScheduleGroup ExpectedSlotGroup 
32  32   2   492    32 
33  32   6   492    33 
34  32   5   492    34 
35  32   6   492    35 
36  32   6   492    35 
37  32   6   492    35 
38  32   6   493    35 
39  32   6   492    35 
Slot SlotGroup EventNum ScheduleGroup ExpectedSlotGroup 
219  219   18   065    219 
220  219   16   065    220 
221  219   1   246    220 
222  219   16   065    220 
223  219   18   065    223 
Slot SlotGroup EventNum ScheduleGroup ExpectedSlotGroup 
39  39   10   113    39 
40  39   9   113    40 
41  39   10   112    40 
42  39   9   112    42 
43  39   1   241    42 
44  39   2   241    44 
45  39   2   241    44 
46  39   1   241    46 
47  39   1   241    46 
48  39   2   241    48 
Slot SlotGroup EventNum ScheduleGroup ExpectedSlotGroup 
46  46   14   184    46 
47  46   14   183    46 
48  46   14   183    46 
49  46   1   184    49 
50  46   15   183    49 
51  46   15   183    49 
Slot SlotGroup EventNum ScheduleGroup ExpectedSlotGroup 
148  148   6   725    148 
149  148   5   725    149 
150  148   5   725    149 
151  148   6   725    151 
152  148   6   723    151 
153  148   6   724    151 
Slot SlotGroup EventNum ScheduleGroup ExpectedSlotGroup 
150  150   2   221    150 
151  150   1   221    151 
152  150   2   221    152 
153  150   2   221    152 
154  150   1   222    152 
Slot SlotGroup EventNum ScheduleGroup ExpectedSlotGroup 
122  122   3   462    122 
123  122   2   462    123 
124  122   2   463    123 
125  122   2   463    123 
Slot SlotGroup EventNum ScheduleGroup ExpectedSlotGroup 
36  36   10   617    36 
37  36   9   617    37 
38  36   10   618    37 
39  36   9   618    39 
Slot SlotGroup EventNum ScheduleGroup ExpectedSlotGroup 
97  97   22   091    97 
98  97   22   091    97 
99  97   21   091    99 
100  97   22   091    100 
101  97   14   092    100 
Slot SlotGroup EventNum ScheduleGroup ExpectedSlotGroup 
108  108   22   463    108 
109  108   23   460    108 
110  108   23   460    108 
111  108   22   461    108 
112  108   22   461    108 
113  113   21   462    113 
114  113   21   462    113 
115  113   22   463    113 
Slot SlotGroup EventNum ScheduleGroup ExpectedSlotGroup 
156  156   11   462    156 
157  156   10   462    157 
158  156   10   463    157 
159  156   10   463    157 
Slot SlotGroup EventNum ScheduleGroup ExpectedSlotGroup 
20  20   8   283    20 
21  21   7   283    21 
22  22   9   283    22 
23  23   8   283    23 
24  24   11   283    24 
25  25   10   283    25 
26  26   12   283    26 
27  26   11   283    27 
28  26   4   282    27 
29  26   4   282    27 
Slot SlotGroup EventNum ScheduleGroup ExpectedSlotGroup 
105  105   2   418    105 
106  106   1   418    106 
107  106   1   418    106 
108  108   2   418    108 
109  106   1   418    109 
110  106   1   418    109 
111  108   2   418    111 
Slot SlotGroup EventNum ScheduleGroup ExpectedSlotGroup 
57  57   13   776    57 
58  57   14   777    57 
59  57   15   777    59 
60  57   15   777    59 
61  61   14   776    61 
Slot SlotGroup EventNum ScheduleGroup ExpectedSlotGroup 
9  9   3   771    9 
10  9   3   771    9 
11  9   3   771    9 
12  9   3   771    9 
13  9   1   772    9 
14  9   1   772    9 
Slot SlotGroup EventNum ScheduleGroup ExpectedSlotGroup 
81  81   21   267    81 
82  81   22   267    82 
83  81   21   267    83 
84  81   21   267    83 
85  85   22   267    85 
86  85   22   267    85 
87  85   21   267    87 
+0

예상 슬롯 그룹은 다른 테스트 세트에서 유사한 상황에서 변경되지 않는 경우에 변경 이유를 설명하세요 ddl 및 샘플 데이터는 여기에 있습니까? 그렇지 않으면 누구도 도움을 많이 할 수 없습니다. –

+0

@SeanLange 불행히도 조금 더 나은 수행을 위해 오래된 상속 된 코드를 만들려고 노력하고 있기 때문에이 모든 것을 얻을 수 있습니다. – Simone

+0

슬롯 그룹이 항상 이상한 이유가 있습니까? 또는 업데이트 할 때 2 씩 증가하고 있습니까? – SqlZim

답변

0

은 (커서를 실행.

rextester 데모 : http://rextester.com/ZOH27910

+---------+------+-----------+----------+---------------+-------------------+----------+ 
| TestSet | slot | slotgroup | eventnum | schedulegroup | expectedslotgroup | conflict | 
+---------+------+-----------+----------+---------------+-------------------+----------+ 
|  6 | 46 |  46 |  14 |   184 |    46 |   | 
|  6 | 47 |  46 |  14 |   183 |    46 |   | 
|  6 | 48 |  46 |  14 |   183 |    46 |   | 
|  6 | 49 |  46 |  1 |   184 |    49 | X  | 
|  6 | 50 |  46 |  15 |   183 |    49 | X  | 
|  6 | 51 |  46 |  15 |   183 |    49 | X  | 
+---------+------+-----------+----------+---------------+-------------------+----------+ 

전체 결과 현재 : 대한을 게시하는 방법

+---------+------+-----------+----------+---------------+-------------------+----------+ 
| TestSet | slot | slotgroup | eventnum | schedulegroup | expectedslotgroup | conflict | 
+---------+------+-----------+----------+---------------+-------------------+----------+ 
|  1 | 8 |   8 |  1 |   978 |     8 |   | 
|  1 | 9 |   9 |  2 |   978 |     9 |   | 
|  1 | 10 |   9 |  2 |   977 |     9 |   | 
|  1 | 11 |   9 |  2 |   977 |     9 |   | 
|  1 | 12 |  12 |  1 |   977 |    12 |   | 
|  1 | 13 |  12 |  2 |   978 |    12 |   | 
|  1 | 14 |  14 |  1 |   978 |    14 |   | 
|  1 | 15 |  15 |  2 |   978 |    15 |   | 
|  1 | 16 |  16 |  1 |   978 |    16 |   | 
|  2 | 17 |  17 |  1 |   331 |    17 |   | 
|  2 | 18 |  17 |  1 |   331 |    17 |   | 
|  2 | 19 |  17 |  1 |   331 |    17 |   | 
|  2 | 20 |  17 |  1 |   331 |    17 |   | 
|  2 | 21 |  17 |  1 |   331 |    17 |   | 
|  2 | 22 |  17 |  1 |   331 |    17 |   | 
|  2 | 23 |  17 |  1 |   331 |    17 |   | 
|  2 | 24 |  17 |  1 |   330 |    17 |   | 
|  2 | 25 |  17 |  1 |   330 |    17 |   | 
|  2 | 26 |  17 |  1 |   330 |    17 |   | 
|  2 | 27 |  17 |  1 |   330 |    17 |   | 
|  2 | 28 |  17 |  1 |   330 |    17 |   | 
|  2 | 29 |  17 |  1 |   330 |    17 |   | 
|  2 | 30 |  17 |  1 |   330 |    17 |   | 
|  2 | 31 |  31 |  2 |   330 |    31 |   | 
|  2 | 32 |  31 |  2 |   330 |    31 |   | 
|  2 | 33 |  31 |  2 |   330 |    31 |   | 
|  2 | 34 |  31 |  2 |   330 |    31 |   | 
|  2 | 35 |  31 |  2 |   330 |    31 |   | 
|  2 | 36 |  31 |  2 |   330 |    31 |   | 
|  2 | 37 |  31 |  2 |   330 |    31 |   | 
|  2 | 38 |  31 |  2 |   331 |    31 |   | 
|  2 | 39 |  31 |  2 |   331 |    31 |   | 
|  2 | 40 |  31 |  2 |   331 |    31 |   | 
|  2 | 41 |  31 |  2 |   331 |    31 |   | 
|  2 | 42 |  31 |  2 |   331 |    31 |   | 
|  2 | 43 |  31 |  2 |   331 |    31 |   | 
|  2 | 44 |  31 |  2 |   331 |    31 |   | 
|  3 | 32 |  32 |  2 |   492 |    32 |   | 
|  3 | 33 |  33 |  6 |   492 |    33 |   | 
|  3 | 34 |  34 |  5 |   492 |    34 |   | 
|  3 | 35 |  35 |  6 |   492 |    35 |   | 
|  3 | 36 |  35 |  6 |   492 |    35 |   | 
|  3 | 37 |  35 |  6 |   492 |    35 |   | 
|  3 | 38 |  35 |  6 |   493 |    35 |   | 
|  3 | 39 |  35 |  6 |   492 |    35 |   | 
|  4 | 219 |  219 |  18 |   65 |    219 |   | 
|  4 | 220 |  220 |  16 |   65 |    220 |   | 
|  4 | 221 |  220 |  1 |   246 |    220 |   | 
|  4 | 222 |  220 |  16 |   65 |    220 |   | 
|  4 | 223 |  223 |  18 |   65 |    223 |   | 
|  5 | 39 |  39 |  10 |   113 |    39 |   | 
|  5 | 40 |  40 |  9 |   113 |    40 |   | 
|  5 | 41 |  40 |  10 |   112 |    40 |   | 
|  5 | 42 |  42 |  9 |   112 |    42 |   | 
|  5 | 43 |  42 |  1 |   241 |    42 |   | 
|  5 | 44 |  44 |  2 |   241 |    44 |   | 
|  5 | 45 |  44 |  2 |   241 |    44 |   | 
|  5 | 46 |  46 |  1 |   241 |    46 |   | 
|  5 | 47 |  46 |  1 |   241 |    46 |   | 
|  5 | 48 |  48 |  2 |   241 |    48 |   | 
|  6 | 46 |  46 |  14 |   184 |    46 |   | 
|  6 | 47 |  46 |  14 |   183 |    46 |   | 
|  6 | 48 |  46 |  14 |   183 |    46 |   | 
|  6 | 49 |  46 |  1 |   184 |    49 | X  | 
|  6 | 50 |  46 |  15 |   183 |    49 | X  | 
|  6 | 51 |  46 |  15 |   183 |    49 | X  | 
|  7 | 148 |  148 |  6 |   725 |    148 |   | 
|  7 | 149 |  149 |  5 |   725 |    149 |   | 
|  7 | 150 |  149 |  5 |   725 |    149 |   | 
|  7 | 151 |  151 |  6 |   725 |    151 |   | 
|  7 | 152 |  151 |  6 |   723 |    151 |   | 
|  7 | 153 |  151 |  6 |   724 |    151 |   | 
|  8 | 150 |  150 |  2 |   221 |    150 |   | 
|  8 | 151 |  151 |  1 |   221 |    151 |   | 
|  8 | 152 |  152 |  2 |   221 |    152 |   | 
|  8 | 153 |  152 |  2 |   221 |    152 |   | 
|  8 | 154 |  152 |  1 |   222 |    152 |   | 
|  9 | 122 |  122 |  3 |   462 |    122 |   | 
|  9 | 123 |  123 |  2 |   462 |    123 |   | 
|  9 | 124 |  123 |  2 |   463 |    123 |   | 
|  9 | 125 |  123 |  2 |   463 |    123 |   | 
|  10 | 36 |  36 |  10 |   617 |    36 |   | 
|  10 | 37 |  37 |  9 |   617 |    37 |   | 
|  10 | 38 |  37 |  10 |   618 |    37 |   | 
|  10 | 39 |  39 |  9 |   618 |    39 |   | 
|  11 | 97 |  97 |  22 |   91 |    97 |   | 
|  11 | 98 |  97 |  22 |   91 |    97 |   | 
|  11 | 99 |  99 |  21 |   91 |    99 |   | 
|  11 | 100 |  100 |  22 |   91 |    100 |   | 
|  11 | 101 |  100 |  14 |   92 |    100 |   | 
|  12 | 108 |  108 |  22 |   463 |    108 |   | 
|  12 | 109 |  108 |  23 |   460 |    108 |   | 
|  12 | 110 |  108 |  23 |   460 |    108 |   | 
|  12 | 111 |  108 |  22 |   461 |    108 |   | 
|  12 | 112 |  108 |  22 |   461 |    108 |   | 
|  12 | 113 |  113 |  21 |   462 |    113 |   | 
|  12 | 114 |  113 |  21 |   462 |    113 |   | 
|  12 | 115 |  113 |  22 |   463 |    113 |   | 
|  13 | 156 |  156 |  11 |   462 |    156 |   | 
|  13 | 157 |  157 |  10 |   462 |    157 |   | 
|  13 | 158 |  157 |  10 |   463 |    157 |   | 
|  13 | 159 |  157 |  10 |   463 |    157 |   | 
|  14 | 20 |  20 |  8 |   283 |    20 |   | 
|  14 | 21 |  21 |  7 |   283 |    21 |   | 
|  14 | 22 |  22 |  9 |   283 |    22 |   | 
|  14 | 23 |  23 |  8 |   283 |    23 |   | 
|  14 | 24 |  24 |  11 |   283 |    24 |   | 
|  14 | 25 |  25 |  10 |   283 |    25 |   | 
|  14 | 26 |  26 |  12 |   283 |    26 |   | 
|  14 | 27 |  27 |  11 |   283 |    27 |   | 
|  14 | 28 |  27 |  4 |   282 |    27 |   | 
|  14 | 29 |  27 |  4 |   282 |    27 |   | 
|  15 | 105 |  105 |  2 |   418 |    105 |   | 
|  15 | 106 |  106 |  1 |   418 |    106 |   | 
|  15 | 107 |  106 |  1 |   418 |    106 |   | 
|  15 | 108 |  108 |  2 |   418 |    108 |   | 
|  15 | 109 |  109 |  1 |   418 |    109 |   | 
|  15 | 110 |  109 |  1 |   418 |    109 |   | 
|  15 | 111 |  111 |  2 |   418 |    111 |   | 
|  16 | 57 |  57 |  13 |   776 |    57 |   | 
|  16 | 58 |  57 |  14 |   777 |    57 |   | 
|  16 | 59 |  59 |  15 |   777 |    59 |   | 
|  16 | 60 |  59 |  15 |   777 |    59 |   | 
|  16 | 61 |  61 |  14 |   776 |    61 |   | 
|  17 | 9 |   9 |  3 |   771 |     9 |   | 
|  17 | 10 |   9 |  3 |   771 |     9 |   | 
|  17 | 11 |   9 |  3 |   771 |     9 |   | 
|  17 | 12 |   9 |  3 |   771 |     9 |   | 
|  17 | 13 |   9 |  1 |   772 |     9 |   | 
|  17 | 14 |   9 |  1 |   772 |     9 |   | 
|  18 | 81 |  81 |  21 |   267 |    81 |   | 
|  18 | 82 |  82 |  22 |   267 |    82 |   | 
|  18 | 83 |  83 |  21 |   267 |    83 |   | 
|  18 | 84 |  83 |  21 |   267 |    83 |   | 
|  18 | 85 |  85 |  22 |   267 |    85 |   | 
|  18 | 86 |  85 |  22 |   267 |    85 |   | 
|  18 | 87 |  87 |  21 |   267 |    87 |   | 
+---------+------+-----------+----------+---------------+-------------------+----------+ 
+0

감사합니다. 매우 흥미 롭습니다. 그러나 슬롯 59 & 60에는 SlotGroup 59가 있어야하고 Slot 63과 64에는 동일하지 않아야합니다. 또한 더 복잡한 경우에도 실패합니다 (동일한 SlotGroup에서 여러 점프) . 그것은 내가 옳은 방향으로 보인다, 우리가 완벽하게 작동시킬 수 있는지 보자 :) – Simone

+0

@Simone 명확한 설명을 해주신 덕분에 나의 대답이 업데이트되었다. – SqlZim

+0

나는 여전히 그것에 대해 연구하고있다. 불행히도 당신의 솔루션은 완벽하지 않다. 여전히 문제가되는 적어도 두 가지 조합이 있습니다. 제 편집 된 질문을 확인하십시오 – Simone