长 CASE 语句 - 它是否写得尽可能有效?



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

在我开始之前,一切都已经在 Access 中运行,因此这是我尝试将大型报表移动到 SQL 中的尝试。

存储过程工作正常,但是有许多销售渠道由数据的其他部分决定,因此这就是 CASE 语句的用武之地。有些数据是我没想到的渠道,总的来说它只是很长,所以我不知道它是否会看起来更整洁?这可能是一些简单的事情,比如添加括号,但我几乎是自学成才的 SQL,我希望养成好习惯并向其他人学习!

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

所以,我希望结果会像我把它们放在CASE中一样,但是,例如,随着互联网作为呼叫中心回归,我希望

一些结果会回来

我很确定你有一些错误。 缺少andor时应使用括号。 或者,更好的是,使用in.

例如:

WHERE Channel = 'Internet' AND
username = 'InternetUser' AND
mop = 3 OR
mop = 4

应该是:

WHERE Channel = 'Internet' AND
username = 'InternetUser' AND
mop IN (3, 4)

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

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

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
AND

的运算符优先级高于OR。因此,在没有括号的情况下,AND一起进行评估,然后OR.

将运算符的优先级视为不使用括号时条件的粘性。所以有了这个:

Chanel = 'Internet' AND Username = 'InternetUser' AND mop = 3 OR mop = 4`

这粘在一起:

Chanel = 'Internet' AND Username = 'InternetUser' AND mop = 3

因此,OR mop = 4自行进行:

Chanel = 'Internet' AND Username = 'InternetUser' AND mop = 3
OR 
mop = 4

如果用明确的括号表示,则上述评估如下:

(Chanel = 'Internet' AND Username = 'InternetUser' AND mop = 3)
OR 
mop = 4

但这会产生不正确的结果,同样是无括号条件。因此,您需要将括号放在正确的位置以使您的条件正确:

Chanel = 'Internet' AND Username = 'InternetUser' AND (mop = 3 OR mop = 4)

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

Chanel = 'Internet' AND Username = 'InternetUser' AND mop IN (3,4)

AND的优先级高于OR,然后IN的优先级高于AND,所以以上不计算为:

(Chanel = 'Internet' AND Username = 'InternetUser' AND mop) IN (3,4)

相反,首先评估IN,然后AND。所以当明确用括号写时,它是这样评估的:

Chanel = 'Internet' AND Username = 'InternetUser' AND (mop IN (3,4))

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

Chanel = 'Internet' AND Username = 'InternetUser' AND mop IN (3,4)

最新更新