首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >长篇大论的CASE语句--它是否写得尽可能有效?

长篇大论的CASE语句--它是否写得尽可能有效?
EN

Stack Overflow用户
提问于 2019-04-24 20:47:21
回答 3查看 60关注 0票数 1

我正在运行一个存储过程,以便从3月底拉出所有最近销售的报告,并需要该报告保持每日更新,直到5月初(这是一个特定的销售期在这里)。

在我开始之前,所有的东西都已经在Access中运行过了,所以这是我将大型报表移到SQL中的尝试。

存储过程运行良好,但是有许多由数据的其他部分决定的销售渠道,所以这就是CASE语句的用武之地。一些数据是作为通道拉取的,我并不期望它会这样,总体来说它是非常长的,所以我不知道它是否可以看起来更整洁?这可能是一些简单的事情,比如添加括号,但我在SQL方面基本上是自学的,我希望养成良好的习惯,并向其他人学习!

代码语言:javascript
复制
CASE 
        WHEN mop = 0
            AND Channel = 'Internet'
            AND financeinstal = 10
            THEN 'Finance option 10 months'
        WHEN mop = 0
            AND Channel = 'Internet'
            AND financeinstal = 4
            THEN 'Finance option 4'
        WHEN Channel = 'Corporate'
            OR pb = 'PR Department'
            THEN 'Corporate'
        WHEN Channel = 'Call Centre'
            OR username = 'call centre'
            AND mop = 3
            OR mop = 4
            THEN 'Call Centre'
        WHEN Channel = 'Internet'
            AND username = 'InternetUser'
            AND mop = 3
            OR mop = 4
            THEN 'Internet'
        WHEN Channel = 'Premium'
            OR Channel = 'Premium Office'
            THEN 'Premium'
        WHEN Channel = 'Ticket Office'
            AND MOP = 1
            OR MOP = 2
            OR MOP = 3
            OR MOP = 4
            THEN 'Ticket Office (Full Payment)'
        WHEN mop_desc = 'Direct Debit'
            AND mop = 8
            THEN 'Automatic'
        WHEN Channel = 'Ticket'
            THEN 'Ticket'
        ELSE 'Other'
        END AS Sales_Channel

所以,我期待的结果将是我把他们放在情况下,但,例如,一些我希望回来,因为互联网是回来作为呼叫中心

EN

回答 3

Stack Overflow用户

发布于 2019-04-24 20:53:51

我很确定你有一些错误。如果缺少andor,则应使用括号。或者,更好的方法是使用in

例如:

代码语言:javascript
复制
WHERE Channel = 'Internet' AND
      username = 'InternetUser' AND
      mop = 3 OR
      mop = 4

应该是:

代码语言:javascript
复制
WHERE Channel = 'Internet' AND
      username = 'InternetUser' AND
      mop IN (3, 4)
票数 5
EN

Stack Overflow用户

发布于 2019-04-24 21:02:42

您应该能够将case语句重写为到内联表的连接,这样会更快

例如,前两个case语句可以像这样重写

代码语言:javascript
复制
with lookup(mop,channel,finance,return)
AS
(
   SELECT 0, 'Internet', 10, 'Finance option 10 months'
   UNION ALL
   SELECT 0, 'Internet', 4, 'Finance option 4'
)
SELECT 
 -- etc
 -- instead of case
 L.return 
 -- etc
FROM base
JOIN lookup AS L on base.mop = L.mop AND base.Channel = L.channel AND base.financeinstal = L.finance
票数 1
EN

Stack Overflow用户

发布于 2019-04-24 21:33:42

OR相比,AND的运算符优先级更高。因此,在没有括号的情况下,一起计算AND,然后计算OR

考虑运算符的优先级,因为如果没有使用括号,条件将是多么粘性。因此,有了这个:

代码语言:javascript
复制
Chanel = 'Internet' AND Username = 'InternetUser' AND mop = 3 OR mop = 4`

这一点结合在一起:

代码语言:javascript
复制
Chanel = 'Internet' AND Username = 'InternetUser' AND mop = 3

因此,OR mop = 4会自己运行:

代码语言:javascript
复制
Chanel = 'Internet' AND Username = 'InternetUser' AND mop = 3
OR 
mop = 4

如果使用显式括号表示,则上面的计算结果如下所示:

代码语言:javascript
复制
(Chanel = 'Internet' AND Username = 'InternetUser' AND mop = 3)
OR 
mop = 4

但这将产生不正确的结果,对于无括号条件也是如此。所以你需要把括号放在正确的位置,以使你的情况正确:

代码语言:javascript
复制
Chanel = 'Internet' AND Username = 'InternetUser' AND (mop = 3 OR mop = 4)

当您想要将一个字段与多个值进行比较时,SQL有一个OR的简写。它是IN运算符,它不仅在您有许多值要与字段进行比较时很有用,而且在您想要最大限度地减少使用括号时也很有用。因此,使用IN而不是OR

代码语言:javascript
复制
Chanel = 'Internet' AND Username = 'InternetUser' AND mop IN (3,4)

AND的优先级高于OR,因此IN的优先级高于AND,因此不会将以上评估为:

代码语言:javascript
复制
(Chanel = 'Internet' AND Username = 'InternetUser' AND mop) IN (3,4)

取而代之的是,首先计算IN,然后计算AND。所以当显式地写上括号时,它的计算方式是这样的:

代码语言:javascript
复制
Chanel = 'Internet' AND Username = 'InternetUser' AND (mop IN (3,4))

由于INAND具有更高的优先级,因此可以安全地删除mop IN (3,4)周围的括号:

代码语言:javascript
复制
Chanel = 'Internet' AND Username = 'InternetUser' AND mop IN (3,4)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55830428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档