Обновление записей с помощью ключа идентификатора потока - PullRequest
0 голосов
/ 26 января 2020

Я пытаюсь собрать сценарий для обновления столбца ActionTypeID на основе конкретного потока областей для каждого идентификатора посещения.

Существует три области, и посещение может перемещаться между любой из областей и Мне нужно обновить столбец ActionTypeID на основе 5 значений в таблице ActionType.

Лог c для обновления полностью основывается на столбце Area для каждой записи VisitID, где вы можете видеть, как VisitID 100 перемещается из области 1 в 2 в 3. В то время как запись VisitID 101 перемещается из области 1 в 2 и затем обратно к 1 и вперед к 2, а затем к 3. Пожалуйста, смотрите столбец "WhatActionTypeShouldBe".

Какой хороший способ обновить этот столбец для того, что может составить миллионы строк и все виды записей движения по районам?

enter image description here

Пример данных

Create Table #SampleData
(
    VisitID int,
    StartDate datetime,
    EndDate datetime,
    Area tinyint,
    ActionTypeID tinyint,
    WhatActionTypeShouldBe tinyint
)
insert into #SampleData
(
    VisitID,
    StartDate,
    EndDate,
    Area,
    ActionTypeID,
    WhatActionTypeShouldBe
)
select
    100,
    '2020-01-26 00:16:09.800',
    '2020-01-26 00:18:09.800',
    1,
    0,
    1
union 
select
    100,
    '2020-01-26 00:18:09.800',
    '2020-01-26 00:21:09.800',
    2,
    0,
    2
union
select
    100,
    '2020-01-26 00:21:09.800',
    '2020-01-26 00:27:09.800',
    3,
    0,
    3
union
select
    101,
    '2020-01-26 00:16:09.800',
    '2020-01-26 00:18:09.800',
    1,
    0,
    1
union 
select
    101,
    '2020-01-26 00:18:09.800',
    '2020-01-26 00:21:09.800',
    2,
    0,
    2
union
select
    101,
    '2020-01-26 00:21:09.800',
    '2020-01-26 00:24:09.800',
    1,
    0,
    4
union
select
    101,
    '2020-01-26 00:24:09.800',
    '2020-01-26 00:27:09.800',
    2,
    0,
    2
union
select
    101,
    '2020-01-26 00:27:09.800',
    '2020-01-26 00:30:09.800',
    3,
    0,
    3
union
select
    102,
    '2020-01-26 00:24:09.800',
    '2020-01-26 00:27:09.800',
    2,
    0,
    2
union
select
    102,
    '2020-01-26 00:27:09.800',
    '2020-01-26 00:30:09.800',
    3,
    0,
    3
union
select
    103,
    '2020-01-26 00:24:09.800',
    '2020-01-26 00:27:09.800',
    1,
    0,
    1
union
select
    103,
    '2020-01-26 00:27:09.800',
    '2020-01-26 00:30:09.800',
    2,
    0,
    2
union
select
    103,
    '2020-01-26 00:30:09.800',
    '2020-01-26 00:34:09.800',
    3,
    0,
    3
union
select
    103,
    '2020-01-26 00:34:09.800',
    '2020-01-26 00:36:09.800',
    2,
    0,
    5
union
select
    103,
    '2020-01-26 00:36:09.800',
    '2020-01-26 00:37:09.800',
    3,
    0,
    3

Create Table #ActionType
(
    ActionTypeID tinyint,
    ActionTypeName varchar(50)
)

insert into #ActionType
(
    ActionTypeID,
    ActionTypeName
)
select
    1,
    'Visit Started'
union
select
    2,
    'Progress to Area 2'
union
select
    3,
    'Complete Visit in Area 3'
union
select
    4,
    'Return to Area 1'
union
select
    5,
    'Return to Area 2'

select * from #SampleData

select * from #ActionType

drop table #SampleData
drop table #ActionType

Ответы [ 2 ]

1 голос
/ 26 января 2020

Вот альтернативный подход, который отслеживает, где посетитель должен был обновить ActionTypeID:

WITH Actions AS (
  SELECT SampleData.*,
         LAG(AREA, 1, 1) OVER (PARTITION BY VisitID ORDER BY StartDate) AS Last_Area,
         COUNT(CASE WHEN Area = 1 THEN 1 END) OVER (PARTITION BY VisitID ORDER BY StartDate ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS Area_1_Visits
  FROM SampleData
)
UPDATE Actions
  SET ActionTypeID =
       CASE WHEN Area = 1 AND Area_1_Visits = 0 THEN 1
            WHEN Area = 1 AND Area_1_Visits > 0 THEN 4
            WHEN Area = 2 AND Last_Area = 1     THEN 2
            WHEN Area = 2 AND Last_Area = 3     THEN 5
            WHEN Area = 3 THEN 3 
       END

Демонстрация по SQLFiddle

1 голос
/ 26 января 2020

Вы хотите что-то с lag() и другими функциями окна. Это немного сложно, но что-то вроде этого:

with toupdate as (
      select sd.*,
             row_number() over (partition by visitid, area order by startdate) as seqnum
      from #sampledata sd
     )
update toupdate
    set actiontypeid = (case when area = 1 and seqnum = 1 then 1
                             when area = 2 and seqnum = 1 then 2
                             when area = 3 then 3
                             when area = 1 then 4
                             when area = 2 then 5
                        end);

Лог c для «5» совершенно неясен. Тем не менее, что-то вроде этого, кажется, то, что вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...