Циклы обновлений - лучший способ сделать это? - PullRequest
0 голосов
/ 15 ноября 2018

Я застрял на этой проблеме. Я думаю, что мне может понадобиться циклическое обновление (если оно существует), но, может быть, есть лучший способ?

Я работаю с заявками на лекарства по рецептам, так что, по сути, 5 столбцов Пользователь, Drug, RxStartDate, DaySupply и 'RxEndDate' = dateadd (dd, DaySupply-1, RxStartDate)

Если у одного и того же пользователя есть 2 перекрывающихся рецепта (Rx1 EndDate> = Rx2 StartDate), то мне нужно сложить DaySupply вместе.

Как только я подведу итоги DaySupply, RxEndDate увеличится, и мне нужно еще раз проверить, есть ли совпадение в рецепте.

В настоящее время у меня есть следующий код, который я должен запускать и перезапускать, пока у меня больше не будет обновлений, но я знаю, что должен быть лучший способ сделать это ...

UPDATE b
SET b.RxStartDate= a.RxStartDate
FROM RxClaims a
JOIN RxClaims b on a.User=b.User and a.Drug = b.Drug
WHERE b.RxStartDate<= a.RxEndDate 
and a.RxStartDate< b.RxStartDate


SELECT User, Drug, RxStartDate, sum(DaySupply) as DaySupply, 
'RxEndDate' = dateadd(dd, sum(DaySupply)-1, RxStartDate)
into RxClaims2
from RxClaims 
group by User, Drug, RxStartDate

Кто-нибудь думает?

sample data:
User Drug   RxStartDate DaySupply   RxEndDate
Amy Humera  2/12/2017   7   2/18/2017
Amy Humera  2/28/2017   5   3/4/2017
Amy Humera  3/3/2017    5   3/7/2017
Amy Humera  3/8/2017    2   3/9/2017
Amy Humera  3/10/2017   7   3/16/2017
Amy Humera  3/17/2017   30  4/15/2017
Amy Humera  3/22/2017   2   3/23/2017
Amy Humera  3/24/2017   2   3/25/2017
Amy Humera  3/31/2017   3   4/2/2017
Amy Humera  4/7/2017    5   4/11/2017
Amy Humera  4/13/2017   30  5/12/2017

after 1st time running my current code              
User Drug   RxStartDate DaySupply   RxEndDate
Amy Humera  2/12/2017   7   2/18/2017
Amy Humera  2/28/2017   10  3/9/2017
Amy Humera  3/8/2017    2   3/9/2017
Amy Humera  3/10/2017   7   3/16/2017
Amy Humera  3/17/2017   72  5/27/2017

after 2nd time running my current code              
User Drug   RxStartDate DaySupply   RxEndDate
Amy Humera  2/12/2017   7   2/18/2017
Amy Humera  2/28/2017   12  3/11/2017
Amy Humera  3/10/2017   7   3/16/2017
Amy Humera  3/17/2017   72  5/27/2017

after 3rd time running my current code              
User Drug   RxStartDate DaySupply   RxEndDate
Amy Humera  2/12/2017   7   2/18/2017
Amy Humera  2/28/2017   19  3/18/2017
Amy Humera  3/17/2017   72  5/27/2017

after 4th time running my current code              
User Drug   RxStartDate DaySupply   RxEndDate
Amy Humera  2/12/2017   7   2/18/2017
Amy Humera  2/28/2017   91  5/29/2017
There is no more overlap…finished!              

1 Ответ

0 голосов
/ 15 ноября 2018

Я думаю, что решение может быть реализовано только с помощью рекурсии, поскольку должен быть цикл, который вычисляет накопленный DaySupply, и я не вижу способа сделать это с любыми нерекурсивными поисками. Вы можете сделать это с помощью рекурсивного CTE .
Возможная реализация:

DECLARE @test TABLE (
    [User] VARCHAR(100),
    Drug VARCHAR(100),
    RxStartDate DATE,
    DaySupply INT,
    RxEndDate DATE
)

INSERT @test
VALUES
    ('Amy', 'Humera', '2/12/2017', '7', '2/18/2017'),
    ('Amy', 'Humera', '2/28/2017', '5', '3/4/2017'),
    ('Amy', 'Humera', '3/3/2017', '5', '3/7/2017'),
    ('Amy', 'Humera', '3/8/2017', '2', '3/9/2017'),
    ('Amy', 'Humera', '3/10/2017', '7', '3/16/2017'),
    ('Amy', 'Humera', '3/17/2017', '30', '4/15/2017'),
    ('Amy', 'Humera', '3/22/2017', '2', '3/23/2017'),
    ('Amy', 'Humera', '3/24/2017', '2', '3/25/2017'),
    ('Amy', 'Humera', '3/31/2017', '3', '4/2/2017'),
    ('Amy', 'Humera', '4/7/2017', '5', '4/11/2017'),
    ('Amy', 'Humera', '4/13/2017', '30', '5/12/2017'),

    ('Amy', 'Other', '3/24/2017', '7', '3/30/2017'),
    ('Amy', 'Other', '3/31/2017', '3', '4/2/2017'),
    ('Amy', 'Other', '4/7/2017', '5', '4/11/2017'),
    ('Amy', 'Other', '4/13/2017', '30', '5/12/2017'),

    ('Joe', 'Humera', '3/24/2017', '8', '3/31/2017'),
    ('Joe', 'Humera', '3/31/2017', '3', '4/2/2017'),
    ('Joe', 'Humera', '4/12/2017', '5', '4/16/2017'),
    ('Joe', 'Humera', '4/23/2017', '30', '5/22/2017'),

    ('Joe', 'Other', '3/24/2017', '60', '5/23/2017'),
    ('Joe', 'Other', '3/31/2017', '3', '4/2/2017'),
    ('Joe', 'Other', '4/7/2017', '5', '4/11/2017'),
    ('Joe', 'Other', '4/13/2017', '30', '5/12/2017')



-- You can comment this out, it is just to show progress:
SELECT * FROM @test ORDER BY [User], Drug, RxStartDate



DECLARE @test_2 TABLE (
    [User] VARCHAR(100),
    Drug VARCHAR(100),
    RxStartDate_base DATE,
    DaySupplyCumulative INT
)

;WITH CTE_RxEndDateExtended as (
    SELECT [User], Drug, RxStartDate, DaySupply, DaySupply as DaySupplyCumulative, RxStartDate as RxStartDate_base, RxStartDate as RxStartDateExtended, dateadd (dd, DaySupply, RxStartDate) as RxEndDateExtended
    FROM @test
    -- WHERE [User] = 'Amy' and Drug = 'Humera' and RxStartDate = '2/28/2017'
    UNION ALL
    SELECT t.[User], t.Drug, t.RxStartDate, t.DaySupply, c.DaySupplyCumulative + t.DaySupply as DaySupplyCumulative, c.RxStartDate_base, t.RxStartDate as RxStartDateExtended, dateadd (dd, t.DaySupply, c.RxEndDateExtended) as RxEndDateExtended
    FROM CTE_RxEndDateExtended as c INNER JOIN @test as t
        on c.[User] = t.[User] and c.Drug = t.Drug
            and c.RxEndDateExtended >= t.RxStartDate and c.RxStartDateExtended < t.RxStartDate
)
INSERT @test_2
SELECT [User], Drug, RxStartDate_base, MAX (DaySupplyCumulative) as DaySupplyCumulative -- comment this out and use this for debugging: SELECT *
FROM CTE_RxEndDateExtended
GROUP BY [User], Drug, RxStartDate_base -- comment this out for debugging
OPTION (MAXRECURSION 0) -- comment this out and use this for debugging (to avoid infinite loops): OPTION (MAXRECURSION 1000)



-- You can comment this out, it is just to show progress:
SELECT * FROM @test_2
ORDER BY [User], Drug, RxStartDate_base -- comment this out and use this for debugging: ORDER BY [User], Drug, RxStartDate_base, RxStartDate, DaySupplyCumulative



SELECT base.*, dateadd (dd, base.DaySupplyCumulative - 1, base.RxStartDate_base) as RxEndDateCumulative
FROM @test_2 as base LEFT OUTER JOIN @test_2 as filter
    on base.[User] = filter.[User] and base.Drug = filter.Drug
        and base.RxStartDate_base > filter.RxStartDate_base
        and dateadd (dd, base.DaySupplyCumulative, base.RxStartDate_base) <= dateadd (dd, filter.DaySupplyCumulative, filter.RxStartDate_base)
WHERE filter.[User] IS NULL
ORDER BY [User], Drug, RxStartDate_base

Может быть, вам нужно оптимизировать его, упрощая логику. Но будьте осторожны, чтобы не сделать бесконечный цикл. При отладке используйте OPTION (MAXRECURSION N ) с N , отличным от нуля.

...