【发布时间】:2015-12-26 11:21:05
【问题描述】:
我目前有一个 CASE 语句,用于检查某些任务是否完成,然后返回下一个任务的日期。由于任务是有序的,每个 WHEN 语句都会变长,检查之前的每个任务以查看它们是否已完成。由于某种原因,在第一个 WHEN 语句之后,它直接跳到 ELSE(它应该满足第二个或第三个 WHEN 的条件)。
CASE
WHEN T.PRNAME = 'TECH PEP MEETING DATE' AND T.PRSTATUS != 2 THEN (SELECT TO_CHAR(MAX(T.PRFINISH),'DD/MM/YY') FROM PRTASK T WHERE T.PRPROJECTID = INV_INVESTMENTS.ID AND Upper(T.PRNAME) = 'TECH PEP MEETING DATE' AND PRISMILESTONE = 1)
WHEN (T.PRNAME = 'TECH PEP MEETING DATE' AND T.PRSTATUS = 2) AND (T.PRNAME = 'BRU MEETING DATE' AND T.PRSTATUS != 2) THEN (SELECT TO_CHAR(MAX(T.PRFINISH),'DD/MM/YY') FROM PRTASK T WHERE T.PRPROJECTID = INV_INVESTMENTS.ID AND Upper(T.PRNAME) = 'BRU MEETING DATE' AND PRISMILESTONE = 1)
WHEN (T.PRNAME = 'TECH PEP MEETING DATE' AND T.PRSTATUS = 2) AND (T.PRNAME = 'BRU MEETING DATE' AND T.PRSTATUS = 2) AND (T.PRNAME = 'TSC MEETING DATE' AND T.PRSTATUS != 2) THEN (SELECT TO_CHAR(MAX(T.PRFINISH),'DD/MM/YY') FROM PRTASK T WHERE T.PRPROJECTID = INV_INVESTMENTS.ID AND Upper(T.PRNAME) = 'TSC MEETING DATE' AND PRISMILESTONE = 1)
ELSE (SELECT TO_CHAR(MAX(T.PRFINISH),'DD/MM/YY') FROM PRTASK T WHERE T.PRPROJECTID = INV_INVESTMENTS.ID AND Upper(T.PRNAME) = 'END OF EVALUATE PHASE' AND PRISMILESTONE = 1)
END
您需要解决这些类型的多个 WHEN 条件的特定方法吗?
编辑:所以在你们的一些反馈之后,我同意你只需要在每个 WHEN 评估一个任务的想法,因为 CASE 语句一旦找到它的第一个 TRUE 语句就应该退出。但是,已将其更新为:
CASE
WHEN UPPER(T.PRNAME) = 'EVALUATE TECH PEP MEETING DATE' AND T.PRSTATUS != 2 THEN (SELECT TO_CHAR(MAX(T.PRFINISH),'DD/MM/YY') FROM PRTASK T WHERE T.PRPROJECTID = INV_INVESTMENTS.ID AND Upper(T.PRNAME) = 'TECH PEP MEETING DATE' AND PRISMILESTONE = 1 AND ROWNUM = 1)
WHEN UPPER(T.PRNAME) = 'EVALUATE BRU MEETING DATE' AND T.PRSTATUS != 2 THEN (SELECT TO_CHAR(MAX(T.PRFINISH),'DD/MM/YY') FROM PRTASK T WHERE T.PRPROJECTID = INV_INVESTMENTS.ID AND Upper(T.PRNAME) = 'BRU MEETING DATE' AND PRISMILESTONE = 1 AND ROWNUM = 1)
WHEN UPPER(T.PRNAME) = 'EVALUATE TSC MEETING DATE' AND T.PRSTATUS != 2 THEN (SELECT TO_CHAR(MAX(T.PRFINISH),'DD/MM/YY') FROM PRTASK T WHERE T.PRPROJECTID = INV_INVESTMENTS.ID AND Upper(T.PRNAME) = 'TSC MEETING DATE' AND PRISMILESTONE = 1 AND ROWNUM = 1)
ELSE (SELECT TO_CHAR(MAX(T.PRFINISH),'DD/MM/YY') FROM PRTASK T WHERE T.PRPROJECTID = INV_INVESTMENTS.ID AND Upper(T.PRNAME) = 'END OF EVALUATE PHASE' AND PRISMILESTONE = 1)
END
我现在得到:
ORA-01427: single-row subquery returns more than one row
不知道为什么会这样,尤其是在末尾加上ROWNUM = 1 以确保只返回一个结果。
单独运行 THEN 时:
SELECT TO_CHAR(MAX(T.PRFINISH),'DD/MM/YY')
FROM PRTASK T
WHERE T.PRPROJECTID = INV_INVESTMENTS.ID
AND Upper(T.PRNAME) = 'TECH PEP MEETING DATE'
AND PRISMILESTONE = 1
AND ROWNUM = 1
我得到一个结果。如果我的想法是正确的,CASE 语句一旦找到它的第一个 TRUE 语句就会退出,为什么会发现多行?
编辑 2:好的 - 所以我一直在玩这个(因为我仍然找不到合乎逻辑的答案并且我已经取得了一些进展。我现在已经改变了查询的结构方式以下内容:
SELECT DISTINCT To_Char(T.PRFINISH, 'DD/MM/YY'),
T.PRNAME
FROM PRTASK T
LEFT OUTER JOIN INV_INVESTMENTS ON T.PRPROJECTID = INV_INVESTMENTS.ID
WHERE T.PRNAME = CASE
WHEN (T.PRNAME = 'Concept Tech PEP Meeting Date' AND T.PRSTATUS != 2) THEN 'Concept Tech PEP Meeting Date'
WHEN (T.PRNAME = 'Concept BRU Meeting Date' AND T.PRSTATUS != 2) THEN 'Concept BRU Meeting Date'
WHEN (T.PRNAME = 'End of Concept Phase' AND T.PRSTATUS != 2) THEN 'End of Concept Phase'
WHEN (T.PRNAME = 'Evaluate Tech PEP Meeting Date' AND T.PRSTATUS != 2) THEN 'Evaluate Tech PEP Meeting Date'
WHEN (T.PRNAME = 'Evaluate BRU Meeting Date' AND T.PRSTATUS != 2) THEN 'Evaluate BRU Meeting Date'
WHEN (T.PRNAME = 'Evaluate TSC Meeting Date' AND T.PRSTATUS != 2) THEN 'Evaluate TSC Meeting Date'
WHEN (T.PRNAME = 'End of Evaluate Phase' AND T.PRSTATUS != 2) THEN 'End of Evaluate Phase'
WHEN (T.PRNAME = 'End of Analyse Phase' AND T.PRSTATUS != 2) THEN 'End of Analyse Phase'
WHEN (T.PRNAME = 'End of Design Phase' AND T.PRSTATUS != 2) THEN 'End of Design Phase'
WHEN (T.PRNAME = 'End of Build Phase' AND T.PRSTATUS != 2) THEN 'End of Build Phase'
WHEN (T.PRNAME = 'End of Test Phase' AND T.PRSTATUS != 2) THEN 'End of Test Phase'
WHEN (T.PRNAME = 'In Service' AND T.PRSTATUS != 2) THEN 'In Service'
WHEN (T.PRNAME = 'End of Implement Phase' AND T.PRSTATUS != 2) THEN 'End of Implement Phase'
WHEN (T.PRNAME = 'End of Closure Phase' AND T.PRSTATUS != 2) THEN 'End of Closure Phase'
ELSE 'In Service'
END
AND INV_INVESTMENTS.CODE = '007058'
但是,现在我得到了多个 WHEN 语句返回值。谁能确认 CASE 语句是否真的只返回第一个 TRUE 值?
【问题讨论】:
-
在第二种和第三种情况下,您应该使用 or 语句而不是 AND。例如声明 (T.PRNAME = 'TECH PEP MEETING DATE' AND T.PRSTATUS = 2) AND (T.PRNAME = 'BRU MEETING DATE' AND T.PRSTATUS != 2) 应该这样写 (T.PRNAME = 'TECH PEP 会议日期'和 T.PRSTATUS = 2) 或 (T.PRNAME = 'BRU 会议日期'和 T.PRSTATUS != 2)
-
@Matthew 现在基于您的错误,问题出在您的
SELECT子查询中,它返回超过 1 行/记录,请尝试检查您的SELECT语句,特别是WHERE条件如果为什么它返回超过 1 行。 -
@Matthew 你尝试了第三个
WHEN,那里也有选择语句SELECT TO_CHAR(MAX(T.PRFINISH),'DD/MM/YY') FROM PRTASK T WHERE T.PRPROJECTID = INV_INVESTMENTS.ID AND Upper(T.PRNAME) = 'TSC MEETING DATE' AND PRISMILESTONE = 1 AND ROWNUM = 1,请尝试如果也会返回1条记录。 -
您能否列出查询中使用的所有表及其关系...我可以尝试不同的方法来满足要求!
-
@Matthew Paxman,请修正您的
ELSE声明。它缺少ROWNUM = 1条件
标签: sql case multiple-conditions