2017-06-21 14 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 sysdate ET.empt_start_date AND ET.empt_end_date AND ET.empt_home_team = 'Y' AND sysdate BETWEEN EJ.EMPJOB_START_DATEとEJ.EMPJOB_END_DATE'を参照して、すべての従業員を取得するかどうかを確認してください。 – Eric

答えて

1

設定したいデータを考えてみましょう。 LEFT JOINを実行すると、実際にその中の1つのデータだけが必要なときにテーブル全体に参加しています。 LEFT JOINSのいくつかを修正しました。また、WHERE x NOT IN(SELECT x ....)を実行すると、大きなデータセットでは遅くなります。VERY私はオプティマイザが少しうまく動作するように変更しました。 LEFT JOINを実行します。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

あなたはLEFTを一日中参加できますが、where句はまだフィルタとして機能します。どこの句でそれを試して、あなたが43kをすべて得たら見てください。さらに、行を折りたたむことができるグループ化もあります。 OUTERを回しWHERE句で

+0

さらにGROUP BY句を使用すると、結果セットをグループ化している可能性があります。 –

+0

この情報に感謝しますが、グループ句が必要です。 Where句のクエリが時間切れのエラーで長時間実行されていない – Priyu

1

これらのフィルタは、JOIN INNERに登録しよう:

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 

彼らはテストした属性は、彼らが非マッチした外は、参加している何である(NULLである行を除外しているので行)。

したがって、いくつかのアプローチがあります。第1は、ヌルを許容することである。

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) 

第2は、テーブルをインラインビューに置き換えることです。

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

関連する問題