Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用左外部联接ORACLE SQL将一个表联接到多个表_Sql_Oracle - Fatal编程技术网

使用左外部联接ORACLE SQL将一个表联接到多个表

使用左外部联接ORACLE SQL将一个表联接到多个表,sql,oracle,Sql,Oracle,我需要employee表中的所有数据,所以我使用了left join,但我没有获得employee表中可用的所有行。缺少一些值。请帮助我解决此问题。我在employee中有43000行,但当我使用它时,我仅得到17000行。我不确定我的延迟在哪里。我希望空列作为右表值的主列。您可以整天左连接,您的where子句仍将用作筛选器。尝试使用无where子句,看看是否获得全部43k。另外,您正在分组,这可能会折叠行。您可以整天离开join,您的where子句仍将用作筛选器。尝试使用无where子句,看看

我需要employee表中的所有数据,所以我使用了left join,但我没有获得employee表中可用的所有行。缺少一些值。请帮助我解决此问题。我在employee中有43000行,但当我使用它时,我仅得到17000行。我不确定我的延迟在哪里。我希望空列作为右表值的主列。

您可以整天左连接,您的where子句仍将用作筛选器。尝试使用无where子句,看看是否获得全部43k。另外,您正在分组,这可能会折叠行。

您可以整天离开join,您的where子句仍将用作筛选器。尝试使用无where子句,看看是否获得全部43k。另外,您正在对可能会折叠行的行进行分组。

WHERE子句中的这些筛选器将外部联接转换为内部联接:

    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;
因为它们排除了被测试属性为空的行,这就是它们在不匹配的外部连接行中的情况

所以有两种方法。第一个是允许空值,例如

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 )

哪种方法更适合您取决于数据。测试它们并查看。

WHERE子句中的这些过滤器将外部联接转换为内部联接:

    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;
因为它们排除了被测试属性为空的行,这就是它们在不匹配的外部连接行中的情况

所以有两种方法。第一个是允许空值,例如

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 )

哪种方法更适合您取决于数据。测试它们并查看。

想想你想要的数据集。当您离开JOIN时,您实际上只需要其中一个表中的数据就可以连接整个表。我已经修改了一些你的左连接来考虑这个问题。另外,在x不在的地方进行选择x。。。。在大型数据集上可能非常慢。我已经更改了它,以允许优化器更好地工作。它现在做一个左连接…其中x为NULL。这应该快得多。你对MAXing有什么打算?这个问题相当复杂。在尝试聚合之前,您需要确保获得了所需的初始数据

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

想想你想要的数据集。当您离开JOIN时,您实际上只需要其中一个表中的数据就可以连接整个表。我已经修改了一些你的左连接来考虑这个问题。另外,在x不在的地方进行选择x。。。。在大型数据集上可能非常慢。我已经更改了它,以允许优化器更好地工作。它现在做一个左连接…其中x为NULL。这应该快得多。你对MAXing有什么打算?这个问题相当复杂。在尝试聚合之前,您需要确保获得了所需的初始数据

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

另外,您使用GROUPBY子句-因此,可能您正在对结果进行分组,以获取信息,但我需要GROUP子句,因为我还将使用代码中未提及的Max函数。如果没有where子句,查询将运行很长时间,并出现超时错误,另外您使用GROUP BY子句-因此,可能您正在对结果进行分组,以获取信息,但我需要GROUP子句,因为我还将使用代码中未提及的Max函数。如果没有where子句,查询将运行很长时间,并且出现超时错误。正确表上的where条件将把联接转换为内部联接。删除这些条件以及ET.EMP_开始_日期和ET.EMP_结束_日期之间的sysdate和ET.EMP_home_团队='Y'和EJ.EMPJOB_开始_日期和EJ.EMPJOB_结束_日期之间的sysdate,然后查看是否获得所有结果是否有员工。右表上的WHERE条件将把连接转换为内部连接。删除这些条件和ET.EMPJOB_开始_日期和ET.EMPJOB_结束_日期和ET.EMPJOB_开始_日期和EJ.EMPJOB_结束_日期之间的sysdate,看看是否有所有员工。