2017-06-21 51 views
0
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; 

我想從員工表中的所有數據,所以我用左加入,但我沒有得到所有行是提供員工表中缺少一些值。請幫幫我有了這個 。我在員工中有43000行,但是當我使用這個時,我只有17000行。我不知道我在哪裏滯後。我希望空列作爲主表的右值。加入一個表來使用多個LEFT OUTER JOIN ORACLE SQL

+0

您右側表格中的WHERE條件會將JOIN加入到INNER JOIN中。 – Eric

+0

刪除這些條件AND ET.empt_start_date和ET.empt_end_date AND ET.empt_home_team ='Y' 和EJ.EMPJOB_START_DATE和EJ.EMPJOB_END_DATE'之間的sysdate,並查看您是否獲得所有員工。 – Eric

回答

1

想想你想要的數據。當你加入時,當你真的只需要其中的一個數據時,你就加入了整個表格。我已經修改了一些你的左連接來解決這個問題。另外,做一個WHERE x NOT IN(SELECT x ....)可以是非常大的數據集上的很慢。我已經改變它讓優化器工作得更好一些。它現在做一個LEFT JOIN .... WHERE x是NULL。這應該快很多。你打算在MAXing上做什麼?這個查詢很相關。在嘗試對其進行聚合之前,您要確保獲得所需的初始數據。

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 
+0

感謝它的一些修改! – Priyu

1

您可以一整天都參加,您的where子句仍然會起到過濾器的作用。試試它沒有where子句,看看你是否得到所有43k。另外,你正在分組,這可能是摺疊行。

+0

加上你使用一個GROUP BY子句 - 所以也許你正在分組結果集 –

+0

感謝您的信息,但我需要組子句,因爲我也在這裏使用Max函數(代碼中沒有提到)。沒有where子句查詢運行很久,超時錯誤 – Priyu

1

在WHERE子句轉動OUTER這些濾波器結合成一個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 

因爲它們排除在測試屬性是空(這是它們處於非匹配外接哪些行行)。

所以有幾種方法。首先是允許空值,例如,

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) 

第二個是用內聯視圖替換表,例如,

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 

哪種方法對您更好取決於數據。測試他們,看看。

+0

謝謝它的工作! – Priyu