【问题标题】:SQL optimization Case statementSQL优化Case语句
【发布时间】:2012-05-10 06:22:33
【问题描述】:

我相信我可以通过使用左外连接的 case 语句来优化这个 sql 语句。

但我一直很难设置案例,一个用于总结代码类型 AB、CD,另一个用于所有其余的。

感谢您对此提供的任何帮助或提示。

update billing set payments = isnull(bd1.amount, payments)
, payments = case 
       when payments is null then 0 
       else payments 
     end
, charges = case 
        when bd2.amount is not null then charges 
        when charges is null then 0 
        else charges 
      end
, balance = round(charges + isnull(bd1.amount, bi.payments), 2) 
from billing bi 

left outer join (select inv, round(sum(bd1.bal), 2) amount 
                from "bill" bd1 
                where code_type = 'AB'
                 or code_type = 'CD' 
                group by inv) bd1 
                on bd1.inv = bi.inv 
left outer join (select invoice, round(sum(bd2.bal), 2) amount 
                from "bill" bd2 
                where code_type <> 'AB'
                 and code_type <> 'CD' 
                group by inv) bd2 
                on bd2.inv = bi.inv;

【问题讨论】:

  • 这有效吗?您似乎要更新 payments 列两次。

标签: sql sybase sql-optimization


【解决方案1】:

可能是这样的:

update billing set payments = isnull(bd1.amount, payments)
, payments = isnull(payments, 0)
, charges = isnull(bd2.amount, isnull(charges, 0))
, balance = round(charges + isnull(bd1.amount, bi.payments), 2)
from billing bi 

left outer join (select inv, round(sum(bd1.bal), 2) amount 
                from "bill" bd1 
                where code_type in ('AB', 'CD')
                group by inv) bd1 
                on bd1.inv = bi.inv 
left outer join (select invoice, round(sum(bd2.bal), 2) amount 
                from "bill" bd2 
                where code_type not in ('AB', 'CD')
                group by inv) bd2 
                on bd2.inv = bi.inv;

两个左连接不是问题!

【讨论】:

    【解决方案2】:

    您可以将其简化为使用单个查询而不是两个。您仍然需要它,因为 UPDATE 中的 GROUP BY 不起作用。

    UPDATE bi 
    SET    payments = bd.payments, 
           charges= bd.charges, 
           balance = bd.balance 
    FROM   billing bi 
           LEFT JOIN (SELECT bd.inv, 
                             payments = Round(Sum(CASE 
                                                    WHEN code_type IN ( 'AB' , 'CD' ) THEN 
                                                    bd.bal 
                                                    ELSE 0 
                                                  END), 2), 
                             charges = Round(Sum(CASE 
                                                   WHEN code_type NOT IN ( 'AB' , 'CD' ) THEN 
                                                   bd.bal 
                                                   ELSE 0 
                                                 END), 2), 
                             balance = Round(Sum(bd.bal), 2) 
                      FROM   bill bd 
                      GROUP  BY bd.inv) bd 
             ON bd.inv = bi.inv 
    

    【讨论】:

    • 这是无效的语法。您不能直接在集合列表中使用聚合函数。
    • 是的,对不起,我开始写评论,然后检查 100% 确定它是无效的,所以当我实际发布时,你已经修复了它。您可以使用CASE WHEN Code_Type IN ('AB', 'CD') 而不是Code_Type = 'AB' OR Code_Type = 'CD' 进一步改进这一点
    • 谢谢,这正是我想要的。也许我遗漏了一些东西,但不幸的是,我在尝试运行查询时遇到了错误。 “未找到预期的词法元素:FROM 您在 SELECT 语句中的列定义之后缺少关键字 FROM。在 UPDATE 语句中解析 FROM 关键字后的表名时出现问题”谢谢
    • @Trevor 你有多余的逗号吗?
    • @ConradFrix 不,这可能是我正在使用的数据库管理系统的问题。我会处理它。
    猜你喜欢
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多