我目前有一个 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 值?
最佳答案
T.PRNAME = 'TECH PEP session 日期' 和 T.PRNAME = 'BRU session 日期'?我认为我们在这里遇到了重叠的情况。
我在这里的高度假设是,您有 1 张表,旁边有许多带有状态的任务,那么我认为这里应该发生的事情如下所示。
首先是你的任务表,我自己创建了一些东西。
CREATE TABLE #testtask
(
PRID INT
, PRNAME varchar(50)
, PRSTATUS INT
, PREREQ INT
)
INSERT INTO #testtask VALUES
(1,'TECH PEP MEETING DATE',1,0),
(2,'BRU MEETING DATE',1,1),
(3,'TSC MEETING DATE',1,2)
可能是这样的
然后,我在它自己的表上创建了一个与其先决任务相关的左联接。
SELECT
t1.PRNAME AS [Job]
, t1.PRSTATUS AS [JobStatus]
, t2.PRNAME AS [PreReqJob]
, t2.PRSTATUS AS [PreReqStatus]
INTO #taskList
FROM #testtask t1
LEFT JOIN #testtask t2
ON
t1.PREREQ = t2.PRID
并得到以下结果。
在进入我认为是您的脚本检查每个任务状态与先决任务之前。
SELECT
CASE
WHEN tl.[Job] = 'TECH PEP MEETING DATE' AND tl.[JobStatus] != 2
THEN
-- do your max select here for 'Tech pep'
WHEN tl.[Job] = 'BRU MEETING DATE' AND tl.[JobStatus] != 2 AND tl.[PreReqStatus] = 2
THEN
-- do your max select here for 'Bru meet'
WHEN tl.[Job] = 'TSC MEETING DATE' AND tl.[JobStatus] != 2 AND tl.[PreReqStatus] = 2
THEN
-- do your max select here for 'Tsc meet'
ELSE
-- do your default max date
END AS [Date]
FROM #taskList AS tl
请单独了解这个概念,因为我没有您的实际表格。如果您复制整个内容,您几乎会出错。希望这会有所帮助:)
关于SQL CASE 检查同一列中的两个条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32836168/