【问题标题】:TSQL while loopTSQL while 循环
【发布时间】:2013-02-11 15:59:37
【问题描述】:
UPDATE Houses 
SET    lStatus = U.codesum
FROM   Houses H
JOIN   (SELECT ref, SUM(code) AS codesum
    FROM   Users
    GROUP  BY ref) AS U ON U.ref = H.ref

上面的代码获取每个房子的所有用户(Houses 表)。对所有用户的代码列(用户表)求和。最后更新房屋表的 lstatus 列中的结果。

我的问题是: 我需要重写不是对代码列求和的查询。相反,我想创建案例陈述。例如:

tempvar = 0    //local variable might be required

For each user {

If code == 1 then tempvar += 5

else if code == 2 then tempvar += 10

etc

tempvar = 0;
}

一旦我们遍历了每个房子的所有用户,我们现在可以设置 lStatus = tempvar。 然后应该将下一个房子的 tempvar 重置为 0。

【问题讨论】:

  • 99% 的情况下,如果您认为 SQL Server 中存在“循环”,那么您的思维方式是错误的,并且有一个更好、更有效、基于集合的答案。我不会说总是/从不之类的话,但大多数时候这是非常可靠的。
  • 99.9% 的情况下,有一种方法可以在不循环或使用光标的情况下获得所需的内容。我知道人们在你身上堆积如山,但这是一个防患于未然的坏习惯。这是另一个使用 UDF 解决小型企业问题的示例:granadacoder.wordpress.com/2008/07/24/…

标签: sql-server tsql loops sql-update sum


【解决方案1】:

在编写 SQL 代码时,您应该尽量避免循环和其他过程结构。关系数据库不能轻易地优化这些东西,而且它们的执行速度通常比声明式数据库慢几个数量级。在这种情况下,用您描述的 CASE 语句替换您的 SUM(code) 似乎很简单:

UPDATE Houses 
SET    lStatus = U.codesum
FROM   Houses H
JOIN   (SELECT ref, SUM(CASE code WHEN 1 THEN 5 WHEN 2 THEN 10 ELSE 0 END) AS codesum
    FROM   Users
    GROUP  BY ref) AS U ON U.ref = H.ref

通过这种方式,SUM 仍然可以处理您想象中的临时变量将执行的任务。

另外,如果您有很多案例,您可能会考虑将这些案例放在一个表格中,然后简单地加入该表格以获得您的总和。这可能会更好地维护。我在这里使用了一个表变量,但它可能如下所示:

DECLARE @codes TABLE (
    code INT NOT NULL PRIMARY KEY,
    value INT NOT NULL
)
INSERT INTO @codes SELECT 1, 5
INSERT INTO @codes SELECT 2, 10

UPDATE Houses 
SET    lStatus = U.codesum
FROM   Houses H
JOIN   (SELECT a.ref, SUM(b.value) AS codesum
    FROM   Users a
    JOIN   @codes b on a.code = b.code -- Here we get the values dynamically
    GROUP  BY a.ref) AS U ON U.ref = H.ref

【讨论】:

    【解决方案2】:

    试试这个:

    UPDATE Houses 
    SET    lStatus = U.codesum
    FROM   Houses H
    JOIN   (
                 SELECT ref, SUM(
                                    CASE
                                        WHEN Code = 1
                                        THEN 5
                                        WHEN Code = 2
                                        THEN 10
                                    END
                                ) AS codesum
                 FROM   Users
                 GROUP  BY ref
           ) AS U ON U.ref = H.ref
    

    【讨论】:

      【解决方案3】:

      试试这个:

      UPDATE Houses 
      SET    lStatus = U.code
      FROM   Houses H
      JOIN   (
                   SELECT ref, SUM(
                                      CASE
                                          WHEN Code = 1
                                          THEN 5
                                          WHEN Code = 2
                                          THEN 10
                                          ELSE 0
                                      END
                                  ) AS code
                   FROM   Users
                   GROUP  BY ref
             ) AS U ON U.ref = H.ref
      

      【讨论】:

        猜你喜欢
        • 2013-05-09
        • 2012-08-20
        • 1970-01-01
        • 1970-01-01
        • 2016-04-24
        • 1970-01-01
        • 1970-01-01
        • 2014-11-02
        • 2016-11-27
        相关资源
        最近更新 更多