SELECT DISTINCT 'DATA' AS DSN,
'MASTER' AS ORG_ID,e.emp_id,
e.emp_name AS EMPLOYEE_NUMBER,
e.emp_firstname AS EMPLOYEE_FIRST_NAME,
e.emp_lastname AS EMPLOYEE_LAST_NAME,
e.emp_val20 AS PAY_STATUS,
(NVL(TO_CHAR(PGT.PAYGRPTYP_NAME),'MASTER')) AS PAY_FREQUENCY,
E.EMP_VAL16 AS PAY_CLASS,
SP.SHFTPAT_NAME AS SHIFT_CODE,
WB.WBU_EMAIL AS EMAIL_ADDR,
(NVL(TO_CHAR( DE.DEPT_NAME),'MASTER')) AS DEPARTMENT,
NULL AS HELD_POSTN,
(NVL(TO_CHAR( J.JOB_NAME),'MASTER')) AS JOB_TITLE,
WB. WBU_NAME AS USER_NAME,
(NVL(TO_CHAR(ET.WBT_ID ),'MASTER')) AS TEAM_CODE,
WT.WBT_NAME AS TEAM_NAME,
WT.WBT_DESC AS TEAM_DESC,
(NVL(TO_CHAR(EB.EMPBDG_BADGE_NUMBER),'MASTER')) AS PERMANENT_BADGE_NO
FROM EMPLOYEE E
LEFT JOIN SHIFT_PATTERN SP
ON E.SHFTPAT_ID =SP.SHFTPAT_ID
LEFT JOIN PAY_GROUP PT
ON E.PAYGRP_ID =PT.PAYGRP_ID
LEFT JOIN PAY_GROUP_TYPE PGT
ON PT.PAYGRPTYP_ID =PGT.PAYGRPTYP_ID
LEFT JOIN EMPLOYEE_BADGE EB
ON E.EMP_ID=EB.EMP_ID
LEFT JOIN EMP_UDF_DATA ED
ON E.EMP_ID=ED.EMP_ID
LEFT JOIN WORKBRAIN_USER WB
ON E.EMP_ID=WB.EMP_ID
LEFT JOIN EMP_DEF_LAB D
ON E.EMP_ID=D.EMP_ID
LEFT JOIN DEPARTMENT DE
ON D.DEPT_ID=DE.DEPT_ID
LEFT JOIN EMPLOYEE_JOB EJ
ON E.EMP_ID=EJ.EMP_ID
LEFT JOIN JOB J
ON EJ.JOB_ID=J.JOB_ID
LEFT JOIN EMPLOYEE_TEAM ET
ON E.EMP_ID=ET.EMP_ID
LEFT JOIN WORKBRAIN_TEAM WT
ON ET.WBT_ID=WT.WBT_ID
LEFT JOIN CALC_GROUP CG
ON E.CALCGRP_ID =CG.CALCGRP_ID
WHERE E.EMP_ID NOT IN (SELECT EMP_ID FROM EMPLOYEE_READER_GROUP)
AND sysdate BETWEEN ET.empt_start_date AND ET.empt_end_date
AND ET.empt_home_team = 'Y'
AND sysdate BETWEEN EJ.EMPJOB_START_DATE AND EJ.EMPJOB_END_DATE
GROUP BY E.EMP_ID,
-- ER.rdrgrp_id,
e.emp_name,
e.emp_lastname,
e.emp_firstname,
e.emp_status,
e.emp_val20,
PGT.PAYGRPTYP_NAME,
E.EMP_VAL16,
e.EMP_VAL18,
EB.EMPBDG_BADGE_NUMBER,
WB.WBU_EMAIL,
DE.DEPT_NAME,
J.JOB_NAME,
SP.SHFTPAT_NAME,
WB. WBU_NAME ,
ET.WBT_ID ,
WT.WBT_NAME,
WT.WBT_DESC;
I want all data from employee table so i used left join but i am not getting all rows which is available in employee table some values are missing .Please help me with this . I have 43000 rows in employee but when i am using this i am getting only 17000 rows alone. I am not sure where i am lagging.I want the null column as Master for the right table values.
You can LEFT join all day long, your where clause is still going to function as a filter. Try it with no where clause and see if you get all 43k. Plus you are grouping which could be collapsing rows.
These filters in the WHERE clause turn the OUTER JOIN into an INNER JOIN:
AND sysdate BETWEEN ET.empt_start_date AND ET.empt_end_date
AND ET.empt_home_team = 'Y'
AND sysdate BETWEEN EJ.EMPJOB_START_DATE AND EJ.EMPJOB_END_DATE
Because they exclude rows where the tested attributes are null (which is what they are in a non-matched outer-joined row).
So there are a couple of approaches. The first is to allow for nulls, eg
AND ( ET.empt_home_team is null or
( sysdate BETWEEN ET.empt_start_date AND ET.empt_end_date
AND ET.empt_home_team = 'Y' )
)
AND ( EJ.EMPJOB_START_DATE is null
or sysdate BETWEEN EJ.EMPJOB_START_DATE AND EJ.EMPJOB_END_DATE )
The second is to replace the tables with inline views eg
LEFT JOIN ( select * from EMPLOYEE_TEAM
where sysdate BETWEEN empt_start_date AND empt_end_date
AND empt_home_team = 'Y' ) ET
ON E.EMP_ID=ET.EMP_ID
LEFT JOIN ( select * from EMPLOYEE_JOB
where sysdate BETWEEN EMPJOB_START_DATE AND EMPJOB_END_DATE ) EJ
ON E.EMP_ID=EJ.EMP_ID
Which approach is the better one for you depends on the data. test them and see.
Think of the data you want in sets. When you LEFT JOIN, you're joining the whole tables when you really only need data from one of them. I've modified a few of your LEFT JOINS to factor for this. Also, doing a WHERE x NOT IN (SELECT x....) can be VERY slow on large datasets. I've changed it to allow the optimizer to work a little better. It now does a LEFT JOIN....WHERE x IS NULL. This should work a lot faster. What do you plan on MAXing? This query is pretty involved. You want to make sure you're getting the initial data that you want before you try to aggregate it.
SELECT 'DATA' AS DSN,
'MASTER' AS ORG_ID,e.emp_id,
e.emp_name AS EMPLOYEE_NUMBER,
e.emp_firstname AS EMPLOYEE_FIRST_NAME,
e.emp_lastname AS EMPLOYEE_LAST_NAME,
e.emp_val20 AS PAY_STATUS,
(NVL(TO_CHAR(ptpgt.PAYGRPTYP_NAME),'MASTER')) AS PAY_FREQUENCY, /* From subquery join */
E.EMP_VAL16 AS PAY_CLASS,
SP.SHFTPAT_NAME AS SHIFT_CODE,
WB.WBU_EMAIL AS EMAIL_ADDR,
(NVL(TO_CHAR( DE.DEPT_NAME),'MASTER')) AS DEPARTMENT,
NULL AS HELD_POSTN,
(NVL(TO_CHAR( eej.JOB_NAME),'MASTER')) AS JOB_TITLE, /* From subquery join */
WB. WBU_NAME AS USER_NAME,
(NVL(TO_CHAR(eet.WBT_ID ),'MASTER')) AS TEAM_CODE, /* From subquery join */
WT.WBT_NAME AS TEAM_NAME,
WT.WBT_DESC AS TEAM_DESC,
(NVL(TO_CHAR(EB.EMPBDG_BADGE_NUMBER),'MASTER')) AS PERMANENT_BADGE_NO
FROM EMPLOYEE E
/* This plus WHERE ERG.EMP_ID IS NULL is the same as the subquery filter. But faster. */
LEFT OUTER JOIN EMPLOYEE_READER_GROUP erg ON e.EMP_ID = ERG.EMP_ID
LEFT JOIN SHIFT_PATTERN SP ON E.SHFTPAT_ID =SP.SHFTPAT_ID
LEFT JOIN (
SELECT PT.EMP_ID,PGT.PAYGRPTYP_NAME
FROM PAY_GROUP PT
INNER JOIN PAY_GROUP_TYPE PGT ON PT.PAYGRPTYP_ID =PGT.PAYGRPTYP_ID
) ptpgt ON E.PAYGRP_ID =ptpgt.PAYGRP_ID
LEFT JOIN EMPLOYEE_BADGE EB ON E.EMP_ID=EB.EMP_ID
LEFT JOIN EMP_UDF_DATA ED ON E.EMP_ID=ED.EMP_ID
LEFT JOIN WORKBRAIN_USER WB ON E.EMP_ID=WB.EMP_ID
LEFT JOIN (
SELECT D.EMP_ID, DE.DEPT_NAME
FROM EMP_DEF_LAB D
INNER JOIN DEPARTMENT DE ON D.DEPT_ID=DE.DEPT_ID
) dde ON E.EMP_ID=dde.EMP_ID
LEFT JOIN (
SELECT EJ.EMP_ID, J.JOB_NAME
FROM EMPLOYEE_JOB EJ
INNER JOIN JOB J ON EJ.JOB_ID=J.JOB_ID
WHERE sysdate BETWEEN EJ.EMPJOB_START_DATE AND EJ.EMPJOB_END_DATE
/*
Doublecheck your date filters. Are they getting the edge dates you need?
BETWEEN makes it easy to miss a date, especially if your fields
are DATETIME datatypes.
USE <=/>= to be a bit clearer.
*/
) eej ON E.EMP_ID=eej.EMP_ID
LEFT JOIN (
SELECT ET.EMP_ID, WBT_ID
FROM EMPLOYEE_TEAM ET
INNER JOIN WORKBRAIN_TEAM WT ON ET.WBT_ID=WT.WBT_ID
WHERE
ET.empt_home_team = 'Y'
AND sysdate BETWEEN ET.empt_start_date AND ET.empt_end_date
/*
Doublecheck your date filters. Are they getting the edge dates you need?
BETWEEN makes it easy to miss a date, especially if your fields
are DATETIME datatypes.
USE <=/>= to be a bit clearer.
*/
) eet ON E.EMP_ID=eet.EMP_ID
LEFT JOIN CALC_GROUP CG ON E.CALCGRP_ID=CG.CALCGRP_ID
WHERE
ERG.EMP_ID IS NULL
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.