在 Case 语句中使用计算 - Oracle SQL

Posted

技术标签:

【中文标题】在 Case 语句中使用计算 - Oracle SQL【英文标题】:Using calculation in Case Statement - Oracle SQL 【发布时间】:2014-07-02 01:03:50 【问题描述】:

你好 sql 巫师,

我正在尝试根据特定参数(案例类型)计算 SLA 天数。对于每种案例类型,SLA 天数的计算方式略有不同。我的问题是:我是否使用 CASE STATEMENT 来实现这一目标?我会记下我目前所拥有的,这是行不通的:

fifthlevel --with statement declaring sla days
AS (SELECT

     CASE sla_days
     WHEN fourthlevel.case_type = 'Complaint'
     THEN sla_days =

      ( SELECT COUNT (*)
        FROM (SELECT business_date
              FROM ( SELECT TO_DATE ('01-01-2011', 'dd-mm-yyyy') + LEVEL - 1
                               business_date
                     FROM DUAL
                     CONNECT BY LEVEL <=
                                 TO_DATE ('31-12-2099', 'dd-mm-yyyy')
                               - TO_DATE ('01-01-2011', 'dd-mm-yyyy')
                               + 1) date_tab1
                     WHERE TO_CHAR (business_date, 'DY') NOT IN ('SAT', 'SUN')
                     AND business_date NOT IN (SELECT holiday_dt
                                               FROM cisadm.ci_cal_hol
                                               WHERE calendar_cd = 'WAW01'
                                              )
                   ) work_days1
             WHERE work_days1.business_date > fourthlevel.correspondence_date
             AND work_days1.business_date <= fourthlevel.close_date
             )
     WHEN fourthlevel.case_type = 'Enquiry'
     THEN sla_days = (SELECT COUNT (*)
                      FROM (SELECT business_date
                            FROM (SELECT TO_DATE ('01-01-2011',
                                                   'dd-mm-yyyy')
                                            + LEVEL
                                            - 1
                                               business_date
                                   FROM DUAL
                                   CONNECT BY LEVEL <=TO_DATE('31-12-2099',
                                                                'dd-mm-yyyy')
                                                      TO_DATE('01-01-2011',
                                                              'dd-mm-yyyy')+ 1
                                  ) date_tab1
                            WHERE TO_CHAR (business_date, 'DY') 
                                  NOT IN ('SAT', 'SUN')
                             AND business_date 
                                  NOT IN (SELECT holiday_dt
                                          FROM cisadm.ci_cal_hol
                                          WHERE calendar_cd = 'WAW01'
                                         )
                            ) work_days1
                      WHERE work_days1.business_date > fourthlevel.agreed_Date
                        AND work_days1.business_date <=
                               fourthlevel.close_date
                     )
     END
    FROM fourthlevel,

    fourthlevel.* --also wanting to select * from preceding WITH statement
    FROM fourthlevel)

好的,看起来有点乱,但基本上我试图根据“投诉”和“查询”的 case_types 进行两种不同的计算。

谁能指出我正确的方向?

如果我能提供更多信息,请告诉我。

传奇!

【问题讨论】:

大家好,感谢您的回复,很抱歉我还不能投票。还想知道如果我想要一个指定 SLA 天数是否在阈值内的字段,我是否会使用 CASE。即,一个字段表示 sla_days 是否小于 15,另一个字段表示 sla_days 是否小于 20。它类似于:case when sla_days &lt;=15 then 'Under SLA" WHEN sla_days &gt; 15 then 'Exceeds SLA' 【参考方案1】:

将 work_days1 子查询提取为单独的 cte:

, work_days1 as (
SELECT business_date
       FROM (    SELECT TO_DATE ('01-01-2011', 'dd-mm-yyyy') + LEVEL - 1
                           business_date
                   FROM DUAL
             CONNECT BY LEVEL <=
                             TO_DATE ('31-12-2099', 'dd-mm-yyyy')
                           - TO_DATE ('01-01-2011', 'dd-mm-yyyy')
                           + 1) date_tab1
      WHERE     TO_CHAR (business_date, 'DY') NOT IN ('SAT', 'SUN')
            AND business_date NOT IN (SELECT holiday_dt
                                        FROM cisadm.ci_cal_hol
                                       WHERE calendar_cd = 'WAW01')),
fifthlevel --with statement declaring sla days
 AS (SELECT
 CASE 
 WHEN fourthlevel.case_type = 'Complaint'
 THEN (SELECT COUNT(*) FROM work_days1 WHERE
 work_days1.business_date > fourthlevel.correspondence_date
    AND work_days1.business_date <= fourthlevel.close_date)
 WHEN fourthlevel.case_type = 'Enquiry'
 THEN sla_days = (SELECT COUNT (*) work_days1 WHERE
 work_days1.business_date > fourthlevel.agreed_Date
                    AND work_days1.business_date <=
                           fourthlevel.close_date) END as sla_days, * 
      FROM fourthlevel)

【讨论】:

当我需要为每种案例类型使用完全不同的计算时,您的解决方案也非常有用。感谢您的意见。【参考方案2】:

似乎这两个case_type的唯一区别是work_days1.business_date的条件。因此,您可以将查询压缩,如下所示:

fifthlevel --with statement declaring sla days
AS (
SELECT
  COUNT (*) sla_days
FROM
  (
    SELECT
      business_date
    FROM
      (
        SELECT
          TO_DATE ('01-01-2011', 'dd-mm-yyyy') + LEVEL- 1 business_date
        FROM
          DUAL
          CONNECT BY LEVEL <= TO_DATE ('31-12-2099','dd-mm-yyyy') - TO_DATE ('01-01-2011','dd-mm-yyyy') + 1
      )
      date_tab1
    WHERE TO_CHAR (business_date, 'DY') NOT IN ('SAT', 'SUN')
    AND business_date NOT IN (SELECT holiday_dt FROM cisadm.ci_cal_hol WHERE calendar_cd = 'WAW01')
  )
  work_days1 INNER JOIN fourthlevel
ON
  work_days1.business_date > (
    CASE
      WHEN fourthlevel.case_type = 'Complaint' THEN fourthlevel.correspondence_date
      WHEN fourthlevel.case_type = 'Enquiry' THEN fourthlevel.agreed_Date
    END)
AND work_days1.business_date <= fourthlevel.close_date;

【讨论】:

您的解决方案是我所追求的完美解决方案,但是它给了我不正确的 sla_days。删除内部连接并将 CASE 语句嵌套在 WHERE 子句中为我修复了它。创建内部连接的原因是什么? 我看到 work_days1fourthlevel 使用条件连接(例如 work_days1.business_date &gt; fourthlevel.agreed_Date)。因此,我明确地创建了 INNER JOIN。

以上是关于在 Case 语句中使用计算 - Oracle SQL的主要内容,如果未能解决你的问题,请参考以下文章

在 oracle 的另一个 case 语句中使用 case 语句的结果

在oracle sql语句里有没有if...else...的用法,请各位大侠给个例子看看,灰常感谢!!

Oracle SQL - 带有迭代的 Case 语句

Oracle SQL - 添加 CASE 语句后“不是按表达式分组”

Oracle:在 Where 子句中使用 Case 语句

Oracle:在操作中使用 CASE 语句变量