使用嵌套的 case 语句有点像循环?

Posted

技术标签:

【中文标题】使用嵌套的 case 语句有点像循环?【英文标题】:Using nested case statements somewhat like a loop? 【发布时间】:2013-02-14 13:03:41 【问题描述】:
TASKS         DATE
NOD 1 OUT     2/5/10
NOD 1 IN      NULL 
NOD 2 OUT     2/10/10
NOD 2 IN      2/11/10
NOD 3 OUT     2/15/10
NOD 3 IN      NULL

我需要做的是找到最大的NOD,然后如果NOD有一个IN日期,则将'NO NOD'放在行中,但是如果最大的NOD已发送OUT但未收到IN,则计算发出后的天数。我试图嵌套 case 语句,但发生的是它看到 NOD 2 OUT 然后 IN 并放置“No NOD”文本。我不知道如何让它找到最大的点头。这是我到目前为止所拥有的(我是 SQL 的新手,所以如果有什么问题我很抱歉,而且我知道我的格式不好,但我可以看到这种方式更好。):

CASE 
             WHEN COUNT(DISTINCT DATE_NOD_TBL.COMPLETED_DATE) = '0' THEN 'No NOD Out'
             WHEN  MAX(DATE_NOD_TBL_2.COMPLETED_DATE) IS NOT NULL AND MAX(DATE_NOD_TBL_5.COMPLETED_DATE) IS NOT NULL 
             THEN    (CASE 
                      WHEN MAX(DATE_NOD_TBL_3.COMPLETED_DATE) IS NOT NULL AND MAX(DATE_NOD_TBL_6.COMPLETED_DATE) IS NOT NULL 
                      THEN    (CASE
                               WHEN MAX(DATE_NOD_TBL_4.COMPLETED_DATE) IS NOT NULL AND MAX(DATE_NOD_TBL_7.COMPLETED_DATE) IS NOT NULL 
                               THEN 'No NOD Out_3'
                               ELSE TO_CHAR(TRUNC(SYSDATE - (MAX(DATE_NOD_TBL.COMPLETED_DATE)))) 
                               END)
                      ELSE TO_CHAR(TRUNC(SYSDATE - (MAX(DATE_NOD_TBL.COMPLETED_DATE))))
                      END) 
             ELSE TO_CHAR(TRUNC(SYSDATE - (MAX(DATE_NOD_TBL.COMPLETED_DATE))))
             END   AS "Days Since Last NOD", 

我为表格设置了别名,以便在每个任务中触摸一次表格,如下所示:

DATE_NOD_TBL contains all OUT tasks
DATE_NOD_TBL_2 is NOD 1 OUT
DATE_NOD_TBL_3 is NOD 2 OUT
DATE_NOD_TBL_4 is NOD 3 OUT
DATE_NOD_TBL_5 is NOD 1 IN
DATE_NOD_TBL_6 is NOD 2 IN
DATE_NOD_TBL_7 is NOD 3 IN

我正在使用 10g Oracle SQL。

整个查询:

SELECT DSKMTB_ACTIVITY_TYPE.ACTIVITY_TYPE_LABEL       AS "Project Type",
  MAX(DATE_ISSUED_TBL_3.ASSIGNED_STAFF_ID)                  AS "Project Manager",
  AGENCY_INTEREST_ALT.ALTERNATE_AI_ID                          AS "Farm ID #",
  MTB_PARISH_COUNTY.PARISH_OR_COUNTY_DESC             AS "County",
  MAX(DISTINCT AGENCY_INTEREST.MASTER_AI_NAME)        AS "Operation Name",
  MAX(DATE_RECEIVED_TBL.COMPLETED_DATE)                   AS "Date Received",
  MAX(DATE_NOD_TBL.COMPLETED_DATE)                            AS "NOD Date",
  COUNT(DISTINCT DATE_NOD_TBL.COMPLETED_DATE)         AS "# of NOD's",

--//days since last NOD
 CASE
    WHEN GREATEST(MAX(DATE_NOD_TBL_2.COMPLETED_DATE),
                  MAX(DATE_NOD_TBL_3.COMPLETED_DATE), 
                  MAX(DATE_NOD_TBL_4.COMPLETED_DATE)) <
         GREATEST(MAX(DATE_NOD_TBL_5.COMPLETED_DATE), 
                  MAX(DATE_NOD_TBL_6.COMPLETED_DATE), 
                  MAX(DATE_NOD_TBL_7.COMPLETED_DATE)) 
         THEN TO_CHAR(TRUNC(SYSDATE - (MAX(DATE_NOD_TBL.COMPLETED_DATE))))
    ELSE 'No NOD Out'
END AS "Days Since Last NOD",


  --//net time
  CASE WHEN 
    COUNT(DISTINCT DATE_NOD_TBL.COMPLETED_DATE) = '0' 
      THEN TRUNC(MAX(SYSDATE - DATE_RECEIVED_TBL.COMPLETED_DATE))
    ELSE
  TRUNC(MAX((SYSDATE - DATE_RECEIVED_TBL.COMPLETED_DATE) - 
  --//issued NOD #1/NOD #1 Information Received
  NVL(((CASE WHEN DATE_NOD_TBL_5.STATUS_CODE IS NULL THEN SYSDATE ELSE DATE_NOD_TBL_5.COMPLETED_DATE END) - DATE_NOD_TBL_2.COMPLETED_DATE),'0') -
  --//issued NOD #2/NOD #2 Information Received
  NVL(((CASE WHEN DATE_NOD_TBL_6.STATUS_CODE IS NULL THEN SYSDATE ELSE DATE_NOD_TBL_6.COMPLETED_DATE END) - DATE_NOD_TBL_3.COMPLETED_DATE),'0') -  
  --//issued NOD #3/NOD #3 Information Received
  NVL(((CASE WHEN DATE_NOD_TBL_7.STATUS_CODE IS NULL THEN SYSDATE ELSE DATE_NOD_TBL_7.COMPLETED_DATE END) - DATE_NOD_TBL_4.COMPLETED_DATE),'0')   
  )) END
  AS "Net Time",


  TRUNC(MAX(SysDate - DATE_RECEIVED_TBL.COMPLETED_DATE))  AS "Gross Time",
  MAX(DATE_SITEASSESSMENT_TBL.COMPLETED_DATE)             AS "Site Visit"
FROM DSK_CENTRAL_FILE
INNER JOIN ACTIVITY_TASK_LIST DATE_ISSUED_TBL
ON DATE_ISSUED_TBL.MASTER_AI_ID       = DSK_CENTRAL_FILE.MASTER_AI_ID
AND DATE_ISSUED_TBL.INT_DOC_ID        = DSK_CENTRAL_FILE.INT_DOC_ID
AND DATE_ISSUED_TBL.REFERENCE_TASK_ID = '171'
AND DATE_ISSUED_TBL.STATUS_CODE      IS NULL
INNER JOIN ACTIVITY_TASK_LIST DATE_ISSUED_TBL_2
ON DATE_ISSUED_TBL_2.MASTER_AI_ID       = DSK_CENTRAL_FILE.MASTER_AI_ID
AND DATE_ISSUED_TBL_2.INT_DOC_ID        = DSK_CENTRAL_FILE.INT_DOC_ID
AND DATE_ISSUED_TBL_2.REFERENCE_TASK_ID = '163'
AND DATE_ISSUED_TBL_2.STATUS_CODE      IS NULL
INNER JOIN ACTIVITY_TASK_LIST DATE_ISSUED_TBL_3
ON DATE_ISSUED_TBL_3.MASTER_AI_ID       = DSK_CENTRAL_FILE.MASTER_AI_ID
AND DATE_ISSUED_TBL_3.INT_DOC_ID        = DSK_CENTRAL_FILE.INT_DOC_ID
AND DATE_ISSUED_TBL_3.REFERENCE_TASK_ID = '262'
INNER JOIN ACTIVITY_TASK_LIST DATE_RECEIVED_TBL
ON DATE_RECEIVED_TBL.MASTER_AI_ID       = DSK_CENTRAL_FILE.MASTER_AI_ID
AND DATE_RECEIVED_TBL.INT_DOC_ID        = DSK_CENTRAL_FILE.INT_DOC_ID
AND DATE_RECEIVED_TBL.INT_DOC_ID        = DATE_ISSUED_TBL.INT_DOC_ID
AND DATE_RECEIVED_TBL.MASTER_AI_ID      = DATE_ISSUED_TBL.MASTER_AI_ID
AND DATE_RECEIVED_TBL.REFERENCE_TASK_ID = '571'
AND DATE_RECEIVED_TBL.STATUS_CODE       = '001'
AND DATE_RECEIVED_TBL.COMPLETED_DATE   IS NOT NULL
LEFT OUTER JOIN ACTIVITY_TASK_LIST DATE_NOD_TBL
ON DATE_NOD_TBL.MASTER_AI_ID        = DSK_CENTRAL_FILE.MASTER_AI_ID
AND DATE_NOD_TBL.INT_DOC_ID         = DSK_CENTRAL_FILE.INT_DOC_ID
AND DATE_NOD_TBL.INT_DOC_ID         = DATE_ISSUED_TBL.INT_DOC_ID
AND DATE_NOD_TBL.MASTER_AI_ID       = DATE_ISSUED_TBL.MASTER_AI_ID
AND DATE_NOD_TBL.REFERENCE_TASK_ID IN ( '393','394','395')
LEFT OUTER JOIN ACTIVITY_TASK_LIST DATE_NOD_TBL_8
ON DATE_NOD_TBL_8.MASTER_AI_ID        = DSK_CENTRAL_FILE.MASTER_AI_ID
AND DATE_NOD_TBL_8.INT_DOC_ID         = DSK_CENTRAL_FILE.INT_DOC_ID
AND DATE_NOD_TBL_8.INT_DOC_ID         = DATE_ISSUED_TBL.INT_DOC_ID
AND DATE_NOD_TBL_8.MASTER_AI_ID       = DATE_ISSUED_TBL.MASTER_AI_ID
AND DATE_NOD_TBL_8.REFERENCE_TASK_ID  IN('602','603','608')
LEFT OUTER JOIN ACTIVITY_TASK_LIST DATE_NOD_TBL_2
ON DATE_NOD_TBL_2.MASTER_AI_ID        = DSK_CENTRAL_FILE.MASTER_AI_ID
AND DATE_NOD_TBL_2.INT_DOC_ID         = DSK_CENTRAL_FILE.INT_DOC_ID
AND DATE_NOD_TBL_2.INT_DOC_ID         = DATE_ISSUED_TBL.INT_DOC_ID
AND DATE_NOD_TBL_2.MASTER_AI_ID       = DATE_ISSUED_TBL.MASTER_AI_ID
AND DATE_NOD_TBL_2.REFERENCE_TASK_ID = '393'
LEFT OUTER JOIN ACTIVITY_TASK_LIST DATE_NOD_TBL_3
ON DATE_NOD_TBL_3.MASTER_AI_ID        = DSK_CENTRAL_FILE.MASTER_AI_ID
AND DATE_NOD_TBL_3.INT_DOC_ID         = DSK_CENTRAL_FILE.INT_DOC_ID
AND DATE_NOD_TBL_3.INT_DOC_ID         = DATE_ISSUED_TBL.INT_DOC_ID
AND DATE_NOD_TBL_3.MASTER_AI_ID       = DATE_ISSUED_TBL.MASTER_AI_ID
AND DATE_NOD_TBL_3.REFERENCE_TASK_ID = '394'
LEFT OUTER JOIN ACTIVITY_TASK_LIST DATE_NOD_TBL_4
ON DATE_NOD_TBL_4.MASTER_AI_ID        = DSK_CENTRAL_FILE.MASTER_AI_ID
AND DATE_NOD_TBL_4.INT_DOC_ID         = DSK_CENTRAL_FILE.INT_DOC_ID
AND DATE_NOD_TBL_4.INT_DOC_ID         = DATE_ISSUED_TBL.INT_DOC_ID
AND DATE_NOD_TBL_4.MASTER_AI_ID       = DATE_ISSUED_TBL.MASTER_AI_ID
AND DATE_NOD_TBL_4.REFERENCE_TASK_ID = '395'
LEFT OUTER JOIN ACTIVITY_TASK_LIST DATE_NOD_TBL_5
ON DATE_NOD_TBL_5.MASTER_AI_ID        = DSK_CENTRAL_FILE.MASTER_AI_ID
AND DATE_NOD_TBL_5.INT_DOC_ID         = DSK_CENTRAL_FILE.INT_DOC_ID
AND DATE_NOD_TBL_5.INT_DOC_ID         = DATE_ISSUED_TBL.INT_DOC_ID
AND DATE_NOD_TBL_5.MASTER_AI_ID       = DATE_ISSUED_TBL.MASTER_AI_ID
AND DATE_NOD_TBL_5.REFERENCE_TASK_ID = '603'
LEFT OUTER JOIN ACTIVITY_TASK_LIST DATE_NOD_TBL_6
ON DATE_NOD_TBL_6.MASTER_AI_ID        = DSK_CENTRAL_FILE.MASTER_AI_ID
AND DATE_NOD_TBL_6.INT_DOC_ID         = DSK_CENTRAL_FILE.INT_DOC_ID
AND DATE_NOD_TBL_6.INT_DOC_ID         = DATE_ISSUED_TBL.INT_DOC_ID
AND DATE_NOD_TBL_6.MASTER_AI_ID       = DATE_ISSUED_TBL.MASTER_AI_ID
AND DATE_NOD_TBL_6.REFERENCE_TASK_ID = '602'
LEFT OUTER JOIN ACTIVITY_TASK_LIST DATE_NOD_TBL_7
ON DATE_NOD_TBL_7.MASTER_AI_ID        = DSK_CENTRAL_FILE.MASTER_AI_ID
AND DATE_NOD_TBL_7.INT_DOC_ID         = DSK_CENTRAL_FILE.INT_DOC_ID
AND DATE_NOD_TBL_7.INT_DOC_ID         = DATE_ISSUED_TBL.INT_DOC_ID
AND DATE_NOD_TBL_7.MASTER_AI_ID       = DATE_ISSUED_TBL.MASTER_AI_ID
AND DATE_NOD_TBL_7.REFERENCE_TASK_ID = '608'
LEFT OUTER JOIN ACTIVITY_TASK_LIST DATE_SITEASSESSMENT_TBL
ON DATE_SITEASSESSMENT_TBL.MASTER_AI_ID       = DSK_CENTRAL_FILE.MASTER_AI_ID
AND DATE_SITEASSESSMENT_TBL.INT_DOC_ID        = DSK_CENTRAL_FILE.INT_DOC_ID
AND DATE_SITEASSESSMENT_TBL.INT_DOC_ID        = DATE_ISSUED_TBL.INT_DOC_ID
AND DATE_SITEASSESSMENT_TBL.MASTER_AI_ID      = DATE_ISSUED_TBL.MASTER_AI_ID
AND DATE_SITEASSESSMENT_TBL.REFERENCE_TASK_ID = '201'
INNER JOIN DSKMTB_ACTIVITY_TYPE
ON DSKMTB_ACTIVITY_TYPE.ACTIVITY_CATEGORY_CODE  = DSK_CENTRAL_FILE.ACTIVITY_CATEGORY_CODE
AND DSKMTB_ACTIVITY_TYPE.ACTIVITY_CLASS_CODE    = DSK_CENTRAL_FILE.ACTIVITY_CLASS_CODE
AND DSKMTB_ACTIVITY_TYPE.ACTIVITY_TYPE_CODE     = DSK_CENTRAL_FILE.ACTIVITY_TYPE_CODE
AND DSKMTB_ACTIVITY_TYPE.PROGRAM_CODE           = DSK_CENTRAL_FILE.PROGRAM_CODE
AND DSKMTB_ACTIVITY_TYPE.PROGRAM_CODE           = 'CF'
AND DSKMTB_ACTIVITY_TYPE.ACTIVITY_CATEGORY_CODE = 'ATH'
LEFT OUTER JOIN AGENCY_INTEREST_ALT
ON AGENCY_INTEREST_ALT.MASTER_AI_ID   = DSK_CENTRAL_FILE.MASTER_AI_ID
AND AGENCY_INTEREST_ALT.END_DATE     IS NULL
AND AGENCY_INTEREST_ALT.USER_GROUP_ID = 'CFO'
INNER JOIN AGENCY_INTEREST
ON AGENCY_INTEREST.MASTER_AI_ID = AGENCY_INTEREST_ALT.MASTER_AI_ID
AND AGENCY_INTEREST.INT_DOC_ID  = AGENCY_INTEREST_ALT.INT_DOC_ID
INNER JOIN SUBJ_ITEM_LOC_GOV_WITHIN
ON SUBJ_ITEM_LOC_GOV_WITHIN.MASTER_AI_ID = DSK_CENTRAL_FILE.MASTER_AI_ID
AND SUBJ_ITEM_LOC_GOV_WITHIN.INT_DOC_ID  = AGENCY_INTEREST_ALT.INT_DOC_ID
INNER JOIN MTB_PARISH_COUNTY
ON MTB_PARISH_COUNTY.PARISH_OR_COUNTY_CODE = SUBJ_ITEM_LOC_GOV_WITHIN.PARISH_OR_COUNTY_CODE
WHERE DSK_CENTRAL_FILE.PROGRAM_CODE          = 'CF'
AND DSK_CENTRAL_FILE.INT_DOC_ID             != 0
AND AGENCY_INTEREST_ALT.INT_DOC_ID           = 0
GROUP BY DSKMTB_ACTIVITY_TYPE.ACTIVITY_TYPE_LABEL,
  AGENCY_INTEREST_ALT.ALTERNATE_AI_ID,
  MTB_PARISH_COUNTY.PARISH_OR_COUNTY_DESC
ORDER BY DSKMTB_ACTIVITY_TYPE.ACTIVITY_TYPE_LABEL,
MAX(DATE_RECEIVED_TBL.COMPLETED_DATE)

【问题讨论】:

您能否包含查询的其余部分(至少,连接和分组依据)? 我添加了查询。真是太牛了。 我明白你的意思了! 【参考方案1】:

要比较最大的 IN 日期和最大的 OUT 日期,请尝试:

CASE
    WHEN GREATEST(MAX(DATE_NOD_TBL_2.COMPLETED_DATE),
                  MAX(DATE_NOD_TBL_3.COMPLETED_DATE), 
                  MAX(DATE_NOD_TBL_4.COMPLETED_DATE)) <
         GREATEST(MAX(DATE_NOD_TBL_5.COMPLETED_DATE), 
                  MAX(DATE_NOD_TBL_6.COMPLETED_DATE), 
                  MAX(DATE_NOD_TBL_7.COMPLETED_DATE)) 
         THEN TO_CHAR(TRUNC(SYSDATE - (MAX(DATE_NOD_TBL.COMPLETED_DATE))))
    ELSE 'No NOD Out'
END

要依次比较成对的日期,请尝试:

DECODE(case
           when MAX(DATE_NOD_TBL_4.COMPLETED_DATE) is not null
               then case when MAX(DATE_NOD_TBL_7.COMPLETED_DATE) is null then 'T' end
           else
               case
                   when MAX(DATE_NOD_TBL_3.COMPLETED_DATE) is not null
                       then case when MAX(DATE_NOD_TBL_6.COMPLETED_DATE) is null then 'T' end
                   else
                       case
                           when MAX(DATE_NOD_TBL_2.COMPLETED_DATE) is not null
                               then case when MAX(DATE_NOD_TBL_5.COMPLETED_DATE) is null then 'T' end
                       end
               end
       end, 'T',TO_CHAR(TRUNC(SYSDATE - (MAX(DATE_NOD_TBL.COMPLETED_DATE)))), 'No NOD Out')

【讨论】:

我很确定这与我有同样的错误。因为 NOD #2 既是 OUT 又是 IN,它会停在那里,而不是计算 NOD 3 的未完成天数。 实际上,这里的错误是因为 NOD 2 IN 在 NOD 3 OUT 之后 - 我假设您在前一个 IN 之前不会有新的 OUT。 数据有点乱,我正在努力解决它。对不起,也许我应该这么说。 @user1983682:我已经用替代解决方案更新了答案 - 你可以试试修改后的版本吗? @user1983682:很高兴我能帮上忙!

以上是关于使用嵌套的 case 语句有点像循环?的主要内容,如果未能解决你的问题,请参考以下文章

在 Java 中,如何跳出当前的多重嵌套循环?

面试在Java中如何跳出当前的多重嵌套循环?

在VB中 for 循环嵌套语句的用法语解释(必须清楚!!)

有两个循环,他们是嵌套关系,在内循环中使用break将终止哪一个循环?

java带标签的break语句,跳出多重嵌套循环语句

js中循环嵌套