Home » SQL & PL/SQL » SQL & PL/SQL » Complex query (merged) (10g)
Complex query (merged) [message #644237] |
Sun, 01 November 2015 06:06 |
|
m.abdulhaq
Messages: 254 Registered: April 2013 Location: Ajman
|
Senior Member |
|
|
I want to create absent report for employees , i have two tables in this regards , one is master and the other is transaction , the transaction detail tables stores the record of people who are comming on daily basis , but there is no record stored any where to show if he is absent.What i did to get this output , i am using cartesian product between emp_trans and a view generating number of days in month , to find out which employee the record is missing .Is there a better way to do this as if i model this query on actual data of employee which has more than 2000 rows , the query will hang.
CREATE TABLE emp
(
empno NUMBER(4),
ename VARCHAR2(10 BYTE),
hiredate DATE
);
INSERT INTO EMP(EMPNO,ENAME,HIREDATE) VALUES (1,'JOHN',TO_DATE('01/10/2015','DD/MM/RRRR'));
INSERT INTO EMP(EMPNO,ENAME,HIREDATE) VALUES (2,'JACK',TO_DATE('01/10/2015','DD/MM/RRRR'));
create table emp_trans
(
emp_no NUMBER(4),
emp_dt DATE,
hrs number(8,2));
INSERT INTO EMP_TRANS(EMP_NO,EMP_DT,HRS) VALUES (1,TO_DATE('01/11/2015','DD/MM/RRRR'),8)
INSERT INTO EMP_TRANS(EMP_NO,EMP_DT,HRS) VALUES (1,TO_DATE('02/11/2015','DD/MM/RRRR'),8)
INSERT INTO EMP_TRANS(EMP_NO,EMP_DT,HRS) VALUES (2,TO_DATE('02/11/2015','DD/MM/RRRR'),8)
CREATE OR REPLACE VIEW gen_month_dt
AS
SELECT TRUNC (SYSDATE, 'MM') + LEVEL - 1 dt
FROM DUAL
CONNECT BY LEVEL <= CAST (TO_CHAR (LAST_DAY (SYSDATE), 'dd') AS INT)
ORDER BY 1
select empno,dt,nvl((SELECT NVL(HRS,0) FROM EMP_TRANS
WHERE EMP_NO = emp.empno AND EMP_DT = dt),0) hrs
from gen_month_dt,emp ;
EMPNO,DT,HRS
1,11/1/2015,8
2,11/1/2015,0
1,11/2/2015,8
2,11/2/2015,8
1,11/3/2015,0
2,11/3/2015,0
1,11/4/2015,0
2,11/4/2015,0
1,11/5/2015,0
2,11/5/2015,0
1,11/6/2015,0
2,11/6/2015,0
1,11/7/2015,0
2,11/7/2015,0
1,11/8/2015,0
2,11/8/2015,0
1,11/9/2015,0
2,11/9/2015,0
1,11/10/2015,0
2,11/10/2015,0
1,11/11/2015,0
2,11/11/2015,0
1,11/12/2015,0
2,11/12/2015,0
1,11/13/2015,0
2,11/13/2015,0
1,11/14/2015,0
2,11/14/2015,0
1,11/15/2015,0
2,11/15/2015,0
1,11/16/2015,0
2,11/16/2015,0
1,11/17/2015,0
2,11/17/2015,0
1,11/18/2015,0
2,11/18/2015,0
1,11/19/2015,0
2,11/19/2015,0
1,11/20/2015,0
2,11/20/2015,0
1,11/21/2015,0
2,11/21/2015,0
1,11/22/2015,0
2,11/22/2015,0
1,11/23/2015,0
2,11/23/2015,0
1,11/24/2015,0
2,11/24/2015,0
1,11/25/2015,0
2,11/25/2015,0
1,11/26/2015,0
2,11/26/2015,0
1,11/27/2015,0
2,11/27/2015,0
1,11/28/2015,0
2,11/28/2015,0
1,11/29/2015,0
2,11/29/2015,0
1,11/30/2015,0
2,11/30/2015,0
SELECT EMPno,count(dt) from (
select empno,dt,(nvl((SELECT NVL(HRS,0) FROM EMP_TRANS
WHERE EMP_NO = emp.empno AND EMP_DT = dt),0)) hrs
from gen_month_dt,emp )
where nvl(hrs,0)=0
GROUP BY EMPNO
EMPNO,COUNT(DT)
1,28
2,29
|
|
|
|
Re: Complex query [message #644252 is a reply to message #644239] |
Mon, 02 November 2015 00:57 |
|
m.abdulhaq
Messages: 254 Registered: April 2013 Location: Ajman
|
Senior Member |
|
|
thanks michael, you meant something like this below.In that case we need to filter out more.
SELECT emp_no, emp_dt,dt, ROW_NUMBER () OVER (PARTITION BY emp_no ORDER BY dt) rn
FROM emp_trans, gen_month_dt
WHERE emp_dt(+) = dt
order by emp_no,dt
EMP_NO,EMP_DT,DT,RN
1,11/1/2015,11/1/2015,1
1,11/2/2015,11/2/2015,2
2,11/2/2015,11/2/2015,1
,,11/3/2015,1
,,11/4/2015,2
,,11/5/2015,3
,,11/6/2015,4
,,11/7/2015,5
,,11/8/2015,6
,,11/9/2015,7
,,11/10/2015,8
,,11/11/2015,9
,,11/12/2015,10
,,11/13/2015,11
,,11/14/2015,12
,,11/15/2015,13
,,11/16/2015,14
,,11/17/2015,15
,,11/18/2015,16
,,11/19/2015,17
,,11/20/2015,18
,,11/21/2015,19
,,11/22/2015,20
,,11/23/2015,21
,,11/24/2015,22
,,11/25/2015,23
,,11/26/2015,24
,,11/27/2015,25
,,11/28/2015,26
,,11/29/2015,27
,,11/30/2015,28
|
|
|
|
Re: Complex query [message #644261 is a reply to message #644254] |
Mon, 02 November 2015 03:11 |
|
Michel Cadot
Messages: 68647 Registered: March 2007 Location: Nanterre, France, http://...
|
Senior Member Account Moderator |
|
|
SQL> with
2 cal as (
3 select trunc(sysdate,'MONTH')+level-1 dt
4 from dual
5 connect by level <= extract(day from last_day(sysdate))
6 )
7 select e.emp_no, count(c.dt) nb
8 from cal c
9 left outer join
10 emp_trans e partition by (emp_no)
11 on e.emp_dt = c.dt
12 where e.emp_dt is null
13 group by e.emp_no
14 order by e.emp_no
15 /
EMP_NO NB
---------- ----------
1 28
2 29
[Updated on: Mon, 02 November 2015 03:12] Report message to a moderator
|
|
|
Re: Complex query [message #644284 is a reply to message #644261] |
Mon, 02 November 2015 09:22 |
|
m.abdulhaq
Messages: 254 Registered: April 2013 Location: Ajman
|
Senior Member |
|
|
thanks michael,i did it using partition and right out join, sorry for the delay in posting.
select emp_n,count(missing_dt) from (
SELECT t.emp_no emp_n,x.dt,nvl(t.emp_dt,TO_DATE('01/01/1990')) missing_dt
FROM emp_trans t partition by (emp_no)
right outer join
( select dt from gen_month_dt ) x
on (t.emp_dt = x.dt)
) where missing_dt = TO_DATE('01/01/1990')
group by emp_n
EMP_N,COUNT(MISSING_DT)
1,28
2,29
|
|
|
|
Re: Complex query [message #644326 is a reply to message #644284] |
Tue, 03 November 2015 04:55 |
|
sandeep_orafaq
Messages: 88 Registered: September 2014
|
Member |
|
|
m.abdulhaq wrote on Mon, 02 November 2015 09:22thanks michael,i did it using partition and right out join, sorry for the delay in posting.
select emp_n,count(missing_dt) from (
SELECT t.emp_no emp_n,x.dt,nvl(t.emp_dt,TO_DATE('01/01/1990')) missing_dt
FROM emp_trans t partition by (emp_no)
right outer join
( select dt from gen_month_dt ) x
on (t.emp_dt = x.dt)
) where missing_dt = TO_DATE('01/01/1990')
group by emp_n
EMP_N,COUNT(MISSING_DT)
1,28
2,29
One should always use format while converting string to date. Just a suggestion. It might work for your session but could create issue in another session where NLS_DATE_FORMAT is different from your expectation.
|
|
|
|
Goto Forum:
Current Time: Fri Apr 26 13:40:44 CDT 2024
|