Sql 执行各种更新语句

Sql 执行各种更新语句,sql,sql-server,tsql,sql-server-2012,Sql,Sql Server,Tsql,Sql Server 2012,所以我试图创建一个存储过程,将以前的记录更新为相应的最大值 现在我弄明白了查询,但我希望能够运行此更新四次,因为where子句将基于字段的子字符串。这就是让我困惑的地方 子字符串将检查以下值-“01”、“04”、“012-”、“042-” 有没有一种方法可以在不重写更新4次的情况下做到这一点 这是我的密码- SET XACT_ABORT ON BEGIN TRAN UPDATE Staging..lease SET ls_origleaseamt = l.maxOrigLease FROM

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

现在我弄明白了查询,但我希望能够运行此更新四次,因为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

我在想也许一个环能起作用?但让我困惑的是子字符串长度的变化。

您可以尝试以下方法:

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'
子字符串(ls_leasenbr,1,2)=“04”和子字符串(ls_leasenbr,1,4)=“042-”之间存在一些重叠,这将导致“042-”在CASE语句中优先,因为这似乎是原始语句所做的

可以使用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中


我还想指出,每次插入新记录或更新现有记录时,都需要运行更新,以确保所有内容保持同步。如果您只是创建了一个在需要时返回最大值的视图,可能会更容易一些。

您使用的是哪个版本的SQL Server?@AHiggins我使用的是SQL Server 2012您确定您的更新语句正确吗?
04
更新还将更新
042-
记录。
04
042-
记录将具有相同的最大值。也就是说,它将是
04
042-
记录组合的最大值。对于
01
012-
记录也会发生同样的情况,但是您的代码没有显示
01
更新步骤。为什么不运行4个不同的更新?4个可以使用索引的简单更新可能比1个必须进行表扫描的复杂更新运行得更快。@Rabbit非常感谢您捕捉到了我甚至没有想到的东西!注意,第三个WHEN条件包括MAX中的
042-
记录,即使在这种情况下
042-
记录排在第一位。你应该用一个案例陈述来划分。谢谢!这真的很有帮助。我实际上没有考虑这两个语句的优先级。@Rabbit-你说得对,第三个语句实际上包含了第二个语句,但这就是为什么我把它们按顺序排列。如果数据与“042-”匹配,则case语句将返回该结果,而不转到“04”步骤。我可能需要查看示例数据集来验证所有内容,但我的工作受到问题和原始代码逻辑的限制。@morgb我理解您选择该排序的原因,但它仅适用于以
042-
开头的记录。对前2个字符进行最大分区的其他
04
记录包括
042-
记录。case语句需要进入分区内部。