各种更新语句

时间:2015-12-08 18:06:27

标签: sql sql-server tsql sql-server-2012

所以我试图创建一个存储过程,将先前的记录更新为相应的MAX值。

现在我找到了查询,但我想要的是能够运行此更新四次,因为where子句将基于字段的子字符串。这让我很困惑。

子字符串将检查以下值:' 01',' 04',' 012 - ',' 042 - &# 39;

有没有办法在没有重写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

我在想也许一个循环可以做到这一点?但它的子串长度变化令我感到困惑。

2 个答案:

答案 0 :(得分: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语句中优先考虑,因为它似乎是您原始语句的作用。

答案 1 :(得分: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的视图,那么您可能会更容易。