How to join 2 queries with different number of records and columns in oracle sql?

我只是一个虾纸丫 提交于 2019-12-31 07:48:10

问题


I have three tables:

Employee_leave(EmployeeID,Time_Period,leave_type)  
Employee(EID,Department,Designation) 
 leave_eligibility(Department,Designation, LeaveType, LeavesBalance). 

I want to fetch the number of leaves availed by a particular employee in each LeaveTypes(Category) so I wrote following query Query1

    SELECT LEAVE_TYPE, SUM(TIME_PERIOD) 
    FROM EMPLOYEE_LEAVE 
    WHERE EMPLOYEEID=78 
    GROUP BY LEAVE_TYPE 
    order by leave_type;

output for Query1

Leave_Type     |    SUM(Time_Period)
Casual                         1
Paid                           4
Sick                           1

I want to fetch the number of leaves an employee is eligible for each leave_type(category). Following query Query2 gives the desire result.

    Select UNIQUE Leavetype,LEAVEBALANCE 
    from LEAVE_ELIGIBILITY 
          INNER JOIN EMPLOYEE 
              ON LEAVE_ELIGIBILITY.DEPARTMENT= EMPLOYEE.DEPARTMENT 
                 AND LEAVE_ELIGIBILITY.DESIGNATION= EMPLOYEE.DESIGNATION 
     WHERE EID=78
     order by leavetype;

output for Query2

LeaveType     |    LeaveBalance
Casual                   10
Paid                     15           
Privlage                  6             
Sick                     20

Now I want to join these 2 queries Query1 and Query2 or create view which displays records from both queries. Also as you can see from output there are different no. of records from different queries. For a record which is not present in output of query1, it should display 0 in final output. Like in present case there is no record in output of query1 like privlage but it should display 0 in Sum(time_period) in Privlage of final output. I tried creating views of these 2 queries and then joining them, but I'm unable to run final query.

Code for View 1

create or replace view combo_table1 as 
   Select UNIQUE Leavetype,LEAVEBALANCE,EMPLOYEE.DEPARTMENT,EMPLOYEE.DESIGNATION, EID 
  from LEAVE_ELIGIBILITY 
       INNER JOIN EMPLOYEE 
       ON LEAVE_ELIGIBILITY.DEPARTMENT= EMPLOYEE.DEPARTMENT
       AND LEAVE_ELIGIBILITY.DESIGNATION= EMPLOYEE.DESIGNATION 
        WHERE EID='78'; 

Code for View 2

create or replace view combo_table2 as
    SELECT LEAVE_TYPE, SUM(TIME_PERIOD) AS Leave_Availed 
    FROM EMPLOYEE_LEAVE
    WHERE EMPLOYEEID='78'
    GROUP BY LEAVE_TYPE;

Code for joining 2 views

SELECT combo_table1.Leavetype, combo_table1.LEAVEBALANCE, combo_table2.leave_availed 
FROM combo_table1 v1 
INNER JOIN combo_table2 v2 
ON v1.Leavetype = v2.LEAVE_TYPE;

But I'm getting "%s: invalid identifier" while executing the above query. Also I know I can't use union as it requires same column which here it is not.

I'm using Oracle 11g, so please answer accordingly.

Thanks in advance.

Desired final output

LeaveType  |  LeaveBalance   |   Sum(Time_period)
Casual               10                  1
Paid                 15                  4        
Privlage              6                  0
Sick                 20                  1

回答1:


To get the final desired output ...

"For a record which is not present in output of query1, it should display 0 in final output. "

... use an outer join to tie the taken leave records to the other tables. This will give zero time_duration for leave types which the employee has not taken.

select emp.Employee_ID
       , le.leavetype
       , le.leavebalance 
       , sum (el.Time_Duration) as total_Time_Duration
from employee emp
     inner join leave_eligibility le
          on le.department= emp.department 
             and le.designation= emp.designation 
     left outer join Employee_leave el
           on el.EmployeeID = emp.Employee_ID
           and el.leave_type = le.leavetype        
group by emp.Employee_ID
       , le.leavetype
       , le.leavebalance 
       ;

Your immediate problem:

I'm getting "%s: invalid identifier"

Your view has references to a column EID although none of your posted tables have a column of that name. Likewise there is confusion between Time_Duration and time_period.

More generally, you will find life considerably easier if you use the exact same name for common columns (i.e. consistently use either employee_id or employeeid, don't chop and change).




回答2:


Try this examle:

with t as (
    select 'Casual' as Leave_Type, 1 as Time_Period, 0 as LeaveBalance from dual
    union all
    select 'Paid', 4,0 from dual
    union all
    select 'Sick', 1,0 from dual),
t1 as (
    select 'Casual' as Leave_Type, 0 as Time_Period, 10 as LeaveBalance from dual
    union all
    select 'Paid', 0, 15 from dual
    union all
    select 'Privlage', 0, 6 from dual
    union all
    select 'Sick', 0, 20 from dual)

select Leave_Type, sum(Time_Period), sum(LeaveBalance) 
from(
    select *
    from t
    UNION ALL
    select * from t1
) 
group by Leave_Type 

Ok, edit:

create or replace view combo_table1 as 
Select UNIQUE Leavetype, 0 AS Leave_Availed, LEAVEBALANCE 
from LEAVE_ELIGIBILITY INNER JOIN EMPLOYEE ON LEAVE_ELIGIBILITY.DEPARTMENT= EMPLOYEE.DEPARTMENT AND LEAVE_ELIGIBILITY.DESIGNATION= EMPLOYEE.DESIGNATION 
WHERE EID='78';

create or replace view combo_table2 as 
SELECT LEAVE_TYPE as Leavetype, SUM(TIME_PERIOD) AS Leave_Availed, 0 as LEAVEBALANCE 
FROM EMPLOYEE_LEAVE 
WHERE EMPLOYEEID='78'
GROUP BY LEAVE_TYPE, LEAVEBALANCE;

SELECT Leavetype, sum(LEAVEBALANCE), sum(leave_availed)
FROM (
  select *
    from combo_table1
    UNION ALL
    select * from combo_table2
)
group by Leavetype;


来源:https://stackoverflow.com/questions/44773173/how-to-join-2-queries-with-different-number-of-records-and-columns-in-oracle-sql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!