Обновление SQL с ЗАДЕРЖКОЙ

#sql #sql-server

#sql #sql-сервер

Вопрос:

У меня есть следующее обновление, которое обновляет запись на основе предыдущей записи —

     WITH CTE AS(
    SELECT 
        patient, 
        start,
        CASE 
        WHEN 
            ISNULL(start, '') = '' 
            AND cd = '3'
            AND LAG([thru_dt]) OVER (PARTITION BY [patient] ORDER BY cast(claimno AS int) ASC) BETWEEN CONVERT(VARCHAR, DATEADD(DAY, -30, thru_dt), 112) AND thru_dt
            AND LAG([cd]) OVER (PARTITION BY [patient] ORDER BY cast(claimno AS int) ASC) = '30'      
        THEN LAG([start]) OVER (PARTITION BY [patient] ORDER BY cast(claimno AS int) ASC) 

        WHEN ISNULL(hhstrtdt, '') = '' AND
            ROW_NUMBER() OVER(PARTITION BY patient ORDER BY cast(claimno AS int) DESC) = 1
            AND LAG([cd]) OVER (PARTITION BY [patient] ORDER BY cast(claimno AS int) ASC) = '30'     
            AND LAG([thru_dt]) OVER (PARTITION BY [patient] ORDER BY cast(claimno AS int) ASC) BETWEEN CONVERT(VARCHAR, DATEADD(DAY, -30, thru_dt), 112) AND thru_dt
        THEN LAG([start]) OVER (PARTITION BY [patient] ORDER BY cast(claimno AS int) ASC) 
        ELSE start
    END AS new_start
    FROM table
)
UPDATE CTE 
SET start = new_start
  

Этот запрос обновляет только одну запись за раз. Например, если бы у меня был этот ввод —

 start       patient     cd
20190307    497863693   30
NULL        497863693   30
NULL        497863693   30
NULL        497863693   30
  

Чтобы обновить все 3 строки с нулевым start значением со значением первой строки, мне пришлось бы выполнить запрос 3 раза.

Вывод будет —

 start       patient     cd
20190307    497863693   30
20190307    497863693   30
20190307    497863693   30
20190307    497863693   30
  

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

Комментарии:

1. Используйте max() вместо этого с тем же разделом и упорядочивайте по

2. Я не думаю, что смогу использовать MAX(). Мне нужно, чтобы текущая запись rows была предыдущей записью rows. @Sujitmohanty30

3. Из вашего примера, похоже, что это не разные значения, если я использую lag или max . В любом случае, это мое понимание на данный момент. Было бы неплохо, если бы вы предоставили фактические данные выборки вместо вывода запроса, а затем, по крайней мере, два разных сценария, что обновлять в качестве ожидаемого результата.

4. @Doe . . . Примеры данных, желаемые результаты и четкое объяснение логики были бы полезны. Ваш запрос не соответствует образцу данных.

5. вы ищете последнее значение, отличное от NULL ?

Ответ №1:

Для этого можно использовать накопительный максимум. Если я правильно понимаю, вы хотите сбросить NULL значения в строках с cd = 30 до последнего start значения, когда cd = '30' :

 with toupdate as (
      select t.*,
             max(start) over (partition by patientid order by cast(claimno AS int)) as imputed_start
      from t
      where cd = '30'
     )
update toupdate
    set start = imputed_start
    where start is null or imputed_start <> start;
  

Ответ №2:

Я думаю, что самый простой способ обновить всю таблицу сразу был бы примерно таким

 with rn_cte as (
    select * , row_number() over (partition by patient order by (select null)) rn
    from tTable)
update tTable
  set start=NULl
where rn>=2;