Home > OS >  Oracle sql combine table and do counting
Oracle sql combine table and do counting

Time:06-24

How to count the total project participation (it means the project count) for the project Name Lakers and participate in Client meeting between 12/25-27/2022 for all employee display with the UserAc and their total PJCount?

Also, if the employee UserAc do not appear in the ProjectParticipate. It also need to display their UserAc and the PJCount is 0 in the final output when they are exists in the EMPLOYEE Table.

Table EMPLOYEE:

UserAc
Ken1
John1
Alex1
Dan1

Table ProjectParticipate

PJName    UserAc    PJRn    PDate        PJCount
Lakers    Ken1      0200    12/25/2022   5.3
Lakers    Ken1      0200    12/28/2022   8.7
Lakers    Ken1      0200    12/27/2022   4.3
Bulls     Ken1      0200    12/25/2022   4
Lakers    John1     0100    12/25/2022   6
Lakers    Alex1     0200    12/25/2022   3

Table ProjectGuide

PJName    PJNumber    NumberExplan
Lakers    0100        Phone call
Lakers    0200        Client meeting
Bulls     0100        Phone call
Bulls     0200        Team meeting
State     0100        Discussion
State     0200        Documentation

Here is the current query I develop

Select 
    UserAc,
    COUNT(PJCount) 
from
    ProjectParticipate
Where 
    PJRn = ‘0200’ and PDate BETWEEN 12/25/2022 and 12/27/2022
--it seems to need to use TABLE ProjectGuide to know Project:Lakers, PJNumber:0200 = Client meeting instead of just PJRn = 0200
Group by 
    UserAc

I don’t know how to use and combine 3 tables to fulfill the requirements.

Below is the expected results

UserAc      PJCount
Ken1        9.6
John1       0
Alex1       3
Dan1        0

Thank you so much for your help.

CodePudding user response:

You can use left join to get PJCount of only 'Client meeting' and PDate between 25th and 27th December. Instead of COUNT() you need to use conditional SUM().

Schema and insert statement:

 CREATE TABLE EMPLOYEE(UserAc VARCHAR(50));

 INSERT INTO EMPLOYEE VALUES('Ken1');
 INSERT INTO EMPLOYEE VALUES('John1');
 INSERT INTO EMPLOYEE VALUES('Alex1');
 INSERT INTO EMPLOYEE VALUES('Dan1');

 CREATE TABLE ProjectParticipate(PJName VARCHAR(50), UserAc VARCHAR(50), PJRn VARCHAR(50), PDate DATE, PJCount FLOAT);

 INSERT INTO ProjectParticipate VALUES('Lakers',    'Ken1',      '0200',   DATE'2022-12-25',   5.3);
 INSERT INTO ProjectParticipate VALUES('Lakers',    'Ken1',      '0200',    DATE'2022-12-28',   8.7);
 INSERT INTO ProjectParticipate VALUES('Lakers',    'Ken1',      '0200',    DATE'2022-12-27',   4.3);
 INSERT INTO ProjectParticipate VALUES('Bulls',     'Ken1',      '0200',    DATE'2022-12-25',   4);
 INSERT INTO ProjectParticipate VALUES('Lakers',    'John1',     '0100',    DATE'2022-12-25',   6);
 INSERT INTO ProjectParticipate VALUES('Lakers',    'Alex1',     '0200',    DATE'2022-12-25',   3);

 CREATE Table ProjectGuide(PJName VARCHAR(50),    PJNumber    VARCHAR(50), NumberExplan VARCHAR(50))

 INSERT INTO ProjectGuide VALUES('Lakers','0100','Phone call');
 INSERT INTO ProjectGuide VALUES('Lakers','0200','Client meeting');
 INSERT INTO ProjectGuide VALUES('Bulls','0100','Phone call');
 INSERT INTO ProjectGuide VALUES('Bulls','0200','Team meeting');
 INSERT INTO ProjectGuide VALUES('State','0100','Discussion');
 INSERT INTO ProjectGuide VALUES('State','0200','Documentation');

Query:

 Select 
     E.UserAc,
     SUM(case when PJNumber is not null then PP.PJCount else 0 end ) PJCount
 from
     EMPLOYEE E LEFT JOIN ProjectParticipate PP ON E.UserAc=PP.UserAc
     and PP.PDate BETWEEN DATE'2022-12-25' and DATE'2022-12-27'
     LEFT JOIN ProjectGuide PG ON PP.PJName=PG.PJName AND PP.PJRn=PG.PJNumber 
     and PG.NumberExplan = 'Client meeting'
 
 Group by 
     E.UserAc

Output

USERAC PJCOUNT
Ken1 9.6
Alex1 3
John1 0
Dan1 0

db<>fiddle here

CodePudding user response:

use union. And not count but sum But you are missing the link between EMPLOYEE and ProjectGuide. You need to find or create that relationship Then wrap it all as inline view


SELECT UserAc, Count(cnt)
FROM 
( -- START INLINE VIEW

Select 
    UserAc,
    SUM(PJCount) cnt
from
    ProjectParticipate
Where 
    PJRn = '0200' and 
    (PDate BETWEEN to_date('12/25/2022', 'MM/DD/YYYY') and to_date('12/27/2022', 'MM/DD/YYYY'))
Group by 
    UserAc

UNION

Select 
    st.UserAc,
    0 cnt
from
    ProjectGuide pg inner join 
    some_table st on pg.PJNumber = st.PJNumber -- <-- you nee to find or define this relation
Group By 
    st.UserAc
) T  -- END INLINE VIEW
GROUP BY 
    UserAc

Union suppresses exact records. So, John/9 and John/0 will return 2 records and sum will be correct. This is why you group by again.

CodePudding user response:

Use an IN clause to find the PJ name/number that represent a client meeting. Use an outer join to include users that did not attend. (And use proper date literals. And you get a sum with SUM, not with COUNT.)

select e.userac, coalesce(pp.sum_pjcount, 0) as total
from employee e
left outer join
(
  select userac, sum(pjcount) as sum_pjcount
  from projectparticipate
  where pdate between date '2022-12-25' and date '2022-12-27'
  and (pjname, pjrn) in 
  (
    select pjname, pjnumber
    from projectguide
    where numberexplan = 'Client meeting'
  )
  group by userac
) pp on pp.userac = e.userac
order by e.userac;
  • Related