2015-12-08 4 views
0

Итак, я пытаюсь создать хранимую процедуру, которая будет обновлять предыдущие записи до соответствующего значения MAX.Выполнять различные обновления:

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

Подстрока будет проверять следующие значения - «01», «04», «012-», «042-».

Есть ли способ, которым я могу это сделать, не переписывая обновление 4 раза?

Вот мой код-

SET XACT_ABORT ON 

BEGIN TRAN 


UPDATE Staging..lease 
SET ls_origleaseamt = l.maxOrigLease 
FROM 
(
    select MAX(ls_origleaseamt) AS [maxOrigLease] 
    from Staging..lease 
    where SUBSTRING(ls_leasenbr, 1, 2) = '04' 
) l 
WHERE SUBSTRING(ls_leasenbr,1,2) = '04' 

UPDATE Staging..lease 
SET ls_origleaseamt = l.maxOrigLease 
FROM 
(
    select MAX(ls_origleaseamt) AS [maxOrigLease] 
    from Staging..lease 
    where SUBSTRING(ls_leasenbr, 1, 4) = '012-' 
) l 
WHERE SUBSTRING(ls_leasenbr,1,4) = '012-' 

UPDATE Staging..lease 
SET ls_origleaseamt = l.maxOrigLease 
FROM 
(
    select MAX(ls_origleaseamt) AS [maxOrigLease] 
    from Staging..lease 
    where SUBSTRING(ls_leasenbr, 1, 4) = '042-' 
) l 
WHERE SUBSTRING(ls_leasenbr,1,4) = '042-' 

COMMIT TRAN 

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

+0

Какую версию SQL Server вы используете? – AHiggins

+0

@AHiggins Я использую SQL Server 2012 –

+1

Вы уверены, что ваши утверждения обновления верны? Обновление '04' также обновит записи' 042-'. Записи '04' и' 042-'будут иметь тот же макс. То есть, это будет максимальное количество записей '04' и' 042-'. То же самое произойдет и для записей «01» и «012-», но ваш код не показывает шаг обновления «01». – Rabbit

ответ

1

Вы могли бы попробовать что-то вроде этого:

UPDATE Staging..lease 
SET ls_origleaseamt = l.maxOrigLease 
FROM (
     SELECT 
      CASE 
       WHEN SUBSTRING(ls_leasenbr, 1, 4) = '012-' THEN MAX(ls_origleaseamt) OVER (PARTITION BY SUBSTRING(ls_leasenbr, 1, 4)) 
       WHEN SUBSTRING(ls_leasenbr, 1, 4) = '042-' THEN MAX(ls_origleaseamt) OVER (PARTITION BY SUBSTRING(ls_leasenbr, 1, 4)) 
       WHEN SUBSTRING(ls_leasenbr,1,2) = '04' THEN MAX(ls_origleaseamt) OVER (PARTITION BY SUBSTRING(ls_leasenbr,1,2)) 
       ELSE ls_origleaseamt 
      END AS maxOrigLease 
     FROM Staging..lease 
    ) l 
WHERE SUBSTRING(ls_leasenbr,1,4) IN ('012-','042-') 
OR SUBSTRING(ls_leasenbr,1,2) = '04' 

Существует некоторое перекрытие между SUBSTRING (ls_leasenbr, 1,2) = '04' и SUBSTRING (ls_leasenbr, 1, 4) = '042-', и это приведет к тому, что «042-» будет иметь приоритет в операторе CASE, поскольку это похоже на то, что делает ваш исходный оператор.

+0

Осторожно, третье условие WHEN включает записи '042-' в MAX, даже если записи '042-' приходят первым в CASE. Вы должны разбить оператор CASE. – Rabbit

+0

Спасибо! Это действительно помогло. На самом деле я не думал о приоритете двух. –

+0

@Rabbit - вы правы, что третий оператор действительно будет охватывать второе утверждение, но именно поэтому я поместил их в этом порядке. Если данные соответствуют «042-», то оператор case возвращает этот результат, не переходя на шаг «04». Я, вероятно, должен увидеть образец набора данных, чтобы проверить все, но я работаю в рамках ограничений вопроса и исходной логики кода. – morgb

1

Вы можете использовать синтаксис MAX() OVER(), где вы разбиваете на оператор CASE.

DECLARE @t TABLE (ls_leasenbr VARCHAR(4), ls_origleaseamt INT) 
INSERT INTO @t VALUES ('01', 2), ('012-', 1), ('04', 3), ('042-', 4) 

SELECT 
    *, 
    MAX(ls_origleaseamt) OVER (PARTITION BY 
     CASE 
      WHEN SUBSTRING(ls_leasenbr, 1, 4) = '012-' THEN '012-' 
      WHEN SUBSTRING(ls_leasenbr, 1, 4) = '042-' THEN '042-' 
      WHEN SUBSTRING(ls_leasenbr, 1, 2) = '01' THEN '01' 
      WHEN SUBSTRING(ls_leasenbr, 1, 2) = '04' THEN '04' 
      ELSE NULL 
     END 
    ) AS maxOrigLease 
FROM @t 
WHERE SUBSTRING(ls_leasenbr, 1, 2) IN ('01', '04') 

Я добавил в 01 случае, потому что вы сказали, что один из них, даже если вы не включили его в SQL.

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

Смежные вопросы