SQL CASE checking two conditions from one column

I currently have a CASE statement that checks if certain tasks are complete or not, and then returns the date of the next task. As tasks are ordered, each WHEN statement becomes longer, checking each of the previous tasks to see if they are complete. For some reason, after the first WHEN statement, it passes directly to ELSE (it must match the conditions of the second or third 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

Is there any specific way you need to solve these types of multiple WHEN conditions?

EDIT: So, after some feedback from you guys, I agree with the idea that you only need to evaluate one task for WHEN, because the CASE statement should exit as soon as it finds its first TRUE statement. However, having updated it, follow these steps:

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

Now I get:

ORA-01427: single-row subquery returns more than one row

Not sure why this is so, especially putting ROWNUM = 1in the end to ensure the return of only one result.

When starting THEN on its own:

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

I get one result. If I am right in believing that the CASE statement will exit as soon as it finds its first TRUE statement, why does it find multiple lines?

EDIT 2: Okay - that's why I already talked a bit with this (because I still can’t find a logical answer, and I made some progress. Now I changed the way the query is structured as follows:

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?

+4
5

T.PRNAME = ' PEP DATE' T.PRNAME = 'BRU TEE DATE'? , .

, 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)

, -

enter image description here

, .

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

.

enter image description here

, script .

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

, , . , . , :)

+4

-, case, lad2025 , OR,

CASE
    WHEN T.PRNAME = 'TECH PEP MEETING DATE' AND T.PRSTATUS != 2 THEN ...
    WHEN T.PRNAME = 'BRU MEETING DATE' AND T.PRSTATUS != 2 THEN ...
    WHEN T.PRNAME = 'TSC MEETING DATE' AND T.PRSTATUS != 2 THEN ...
    ELSE ...
END

(
    SELECT TO_CHAR(MAX(T.PRFINISH),'DD/MM/YY') 
    FROM PRTASK T 
    WHERE T.PRPROJECTID = INV_INVESTMENTS.ID 
        AND PRISMILESTONE = 1
        AND Upper(T.PRNAME) = 
            CASE
                WHEN T.PRNAME = 'TECH PEP MEETING DATE' AND T.PRSTATUS != 2 THEN 'TECH PEP MEETING DATE'
                WHEN T.PRNAME = 'BRU MEETING DATE' AND T.PRSTATUS != 2 THEN 'BRU MEETING DATE'
                WHEN T.PRNAME = 'TSC MEETING DATE' AND T.PRSTATUS != 2 THEN 'TSC MEETING DATE'
                ELSE 'END OF EVALUATE PHASE'
            END
)
+2

ROWNUM = 1, , THEN? ROWNUM = 1, ELSE. ROWNUM = 1?

+2

,

, . , sqlfiddle, .

, , . , . .

max (x) - , . , max() , .

+2

CASE WHEN , AND. WHEN FALSE, ? .

    WHEN (T.PRNAME = 'TECH PEP MEETING DATE' AND T.PRSTATUS = 2) 
    AND (T.PRNAME = 'BRU MEETING DATE' AND T.PRSTATUS != 2)
    THEN...

T.PRNAME = 'TECH PEP MEETING DATE AND AND (T.PRNAME = 'BRU MEETING DATE', TRUE WHEN

AND true, AND .

, AND WHEN OR, / T.PRNAME

, , AND OR, .

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) OR (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) OR (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

, .

+1
source

Source: https://habr.com/ru/post/1609418/


All Articles