简体   繁体   中英

Comparing multiple rows and column in oracle

I am working in Oracle SQL, suppose i have a table like this which has start date and completion date for stages of a project.

Project No STAGES Start Date completion date
PROJ_001 1 12-MAR-21 12-MAR-21
PROJ_001 2 14-MAR-21 14-MAR-21
PROJ_001 3 15-MAR-21 15-MAR-21
PROJ_001 4 18-MAR-21 18-MAR-21
PROJ_002 1 16-MAR-21 18-MAR-21
PROJ_002 2 17-MAR-21 19-MAR-21
PROJ_002 3 19-MAR-21 19-MAR-21
PROJ_002 4 21-MAR-21 23-MAR-21

I need to bring the output as the below table. for stage level output, need to compare the completion date and start date and for project level, need to check the last stage of a project (ie stage 4)

Project No STAGES Start Date completion date Output 1 output 2 project level
PROJ_001 1 12-MAR-21 12-MAR-21 ON TIME ON TIME
PROJ_001 2 14-MAR-21 14-MAR-21 ON TIME ON TIME
PROJ_001 3 15-MAR-21 15-MAR-21 ON TIME ON TIME
PROJ_001 4 18-MAR-21 18-MAR-21 ON TIME ON TIME
PROJ_002 1 16-MAR-21 18-MAR-21 DELAYED DELAYED
PROJ_002 2 17-MAR-21 19-MAR-21 DELAYED DELAYED
PROJ_002 3 19-MAR-21 19-MAR-21 ON TIME DELAYED
PROJ_002 4 21-MAR-21 23-MAR-21 DELAYED DELAYED

can anyone help me?

You could write 2 queries, {Q1} returning the values you need for "Output 1", and {2} giving you the values for "Output 2". Once you see that these queries produce the correct result, JOIN them together. Example see DBfiddle .

Query 1 ("stage level")

select 
  projectno, stages, startdate, completiondate 
, case
    when startdate = completiondate then 'on time'
    else 'delayed'
  end output_1
from projects;

Query 2 ("project level")

-- look at the last stage (only).  CASE may need tweaking
select 
  projectno
, case 
    when max( startdate ) = max( completiondate ) then 'on time'
    else 'delayed'
  end output_2  
from projects
group by projectno
;

JOIN

select Q1.*, Q2.output_2
from (
  select 
    projectno, stages, startdate, completiondate 
  , case
      when startdate = completiondate then 'on time'
      else 'delayed'
    end output_1
  from projects
) Q1 join (
  select 
    projectno
  , case 
      when max( startdate ) = max( completiondate ) then 'on time'
      else 'delayed'
    end output_2  
  from projects
  group by projectno
) Q2 on Q1.projectno = Q2.projectno 
order by Q1.projectno, Q1.startdate
;

-- result
PROJECTNO   STAGES  STARTDATE   COMPLETIONDATE  OUTPUT_1  OUTPUT_2
PROJ_001    1      12-MAR-21    12-MAR-21       on time   on time
PROJ_001    2      14-MAR-21    14-MAR-21       on time   on time
PROJ_001    3      15-MAR-21    15-MAR-21       on time   on time
PROJ_001    4      18-MAR-21    18-MAR-21       on time   on time
PROJ_002    1      16-MAR-21    18-MAR-21       delayed   delayed
PROJ_002    2      17-MAR-21    19-MAR-21       delayed   delayed
PROJ_002    3      19-MAR-21    19-MAR-21       on time   delayed
PROJ_002    4      21-MAR-21    23-MAR-21       delayed   delayed

ADDENDUM

( Taking @Thorsten Kettner's suggestion on board: ) You could also use max() in form of an analytic function eg

-- remove the comments -> see the output of max(...) over (...)
select 
  projectno, stages, startdate, completiondate 
, case
    when startdate = completiondate then 'on time'
    else 'delayed'
  end output_1
, case 
    when 
      max( startdate ) over ( partition by projectno  )
    = max( completiondate )  over ( partition by projectno )
    then 'on time'
    else 'delayed'
  end output_2
-- , max( startdate ) over ( partition by projectno  ) maxstart_
-- , max( completiondate )  over ( partition by projectno ) maxcompletion_
from projects;

DBfiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM