Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.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
Sql Oracle 12c—加入最大日期记录的有效方法_Sql_Oracle_Join_Oracle12c - Fatal编程技术网

Sql Oracle 12c—加入最大日期记录的有效方法

Sql Oracle 12c—加入最大日期记录的有效方法,sql,oracle,join,oracle12c,Sql,Oracle,Join,Oracle12c,对于给定的employee_ID,我有以下将表连接到最新记录的方法,我想知道是否有更有效/更快的方法来检索最新记录,最好的方法是什么 SELECT * FROM EMPLOYEE WHERE NOT EXISTS ( SELECT 1 FROM EMPLOYEE D JOIN EMPLOYEE_HISTORY E

对于给定的
employee_ID
,我有以下将表连接到最新记录的方法,我想知道是否有更有效/更快的方法来检索最新记录,最好的方法是什么

SELECT * FROM EMPLOYEE
WHERE NOT EXISTS (
                       SELECT 1
                       FROM EMPLOYEE D
                       JOIN EMPLOYEE_HISTORY E
                               ON  E.EMPLOYEE_ID = D.EMPLOYEE_ID
                               AND E.CREATE_DATE IN (SELECT MAX(CREATE_DATE) 
                                                   FROM EMPLOYEE_HISTORY 
                                                   WHERE EMPLOYEE_ID = D.EMPLOYEE_ID)
                  )
当我将explain计划与下面的查询进行比较时,下面的方法似乎成本更高

SELECT *
FROM EMPLOYEE
WHERE NOT EXISTS 
    (SELECT 1
       FROM EMPLOYEE D
       JOIN   (
            SELECT  E.*
            FROM EMPLOYEE_HISTORY E 
            INNER JOIN  (
                            SELECT  EMPLOYEE_ID
                                ,   MAX(CREATE_DATE) max_date
                            FROM EMPLOYEE_HISTORY E2 
                            GROUP BY EMPLOYEE_ID
                            ) EE
                            ON  EE.EMPLOYEE_ID = E.EMPLOYEE_ID
                            AND EE.max_date = E.CREATE_DATE
              ) A
       ON  A.EMPLOYEE_ID = D.EMPLOYEE_ID 
       AND ROWNUM = 1)
那么这是否意味着它确实更好


创建日期没有索引,但是主键在员工ID上,如果员工的创建日期必须在员工ID历史记录中的最大创建日期之后,则创建日期

那么对于该员工ID,在员工历史记录中不存在相等或更高的创建日期

SELECT * 
FROM EMPLOYEE Emp
WHERE NOT EXISTS (
    SELECT 1
    FROM EMPLOYEE_HISTORY Hist
    WHERE Hist.EMPLOYEE_ID = Emp.EMPLOYEE_ID
      AND Hist.CREATE_DATE >= Emp.CREATE_DATE
)

测试员工的创建日期是否必须在员工历史记录中该员工ID的最大创建日期之后

那么对于该员工ID,在员工历史记录中不存在相等或更高的创建日期

SELECT * 
FROM EMPLOYEE Emp
WHERE NOT EXISTS (
    SELECT 1
    FROM EMPLOYEE_HISTORY Hist
    WHERE Hist.EMPLOYEE_ID = Emp.EMPLOYEE_ID
      AND Hist.CREATE_DATE >= Emp.CREATE_DATE
)

Test

我将使用
=
而不是
中的
编写查询:

 SELECT 1
 FROM EMPLOYEE E JOIN
      EMPLOYEE_HISTORY EH
      ON EH.EMPLOYEE_ID = E.EMPLOYEE_ID AND
         EH.CREATE_DATE = (SELECT MAX(EH2.CREATE_DATE) 
                           FROM EMPLOYEE_HISTORY EH2
                           WHERE EH2.EMPLOYEE_ID = EH.EMPLOYEE_ID
                          );
对于比较而言,
中的
=
更一般

您的主键索引应该用于子查询,这将使它非常快

假设您确实希望返回实际的列,那么我不确定是否有方法可以更快地返回

如果您确实只选择了
1
,那么请忘记最近的记录,只使用
存在的记录即可:

 SELECT 1
 FROM EMPLOYEE E
 WHERE EXISTS (SELECT 1
               FROM EMPLOYEE_HISTORY EH2
               WHERE EH2.EMPLOYEE_ID = E.EMPLOYEE_ID
              );

您的查询检查的唯一附加条件是
CREATE\u DATE
不为空,但我猜这始终是真的。

我将使用
=
而不是
中的
编写查询:

 SELECT 1
 FROM EMPLOYEE E JOIN
      EMPLOYEE_HISTORY EH
      ON EH.EMPLOYEE_ID = E.EMPLOYEE_ID AND
         EH.CREATE_DATE = (SELECT MAX(EH2.CREATE_DATE) 
                           FROM EMPLOYEE_HISTORY EH2
                           WHERE EH2.EMPLOYEE_ID = EH.EMPLOYEE_ID
                          );
对于比较而言,
中的
=
更一般

您的主键索引应该用于子查询,这将使它非常快

假设您确实希望返回实际的列,那么我不确定是否有方法可以更快地返回

如果您确实只选择了
1
,那么请忘记最近的记录,只使用
存在的记录即可:

 SELECT 1
 FROM EMPLOYEE E
 WHERE EXISTS (SELECT 1
               FROM EMPLOYEE_HISTORY EH2
               WHERE EH2.EMPLOYEE_ID = E.EMPLOYEE_ID
              );
您的查询检查的唯一附加条件是
CREATE\u DATE
不为空,但我猜这始终是真的。

使用
RANK
(或
densite\u RANK
ROW\u NUMBER
)分析函数:

SELECT 1
FROM EMPLOYEE E
JOIN   (
  SELECT *
  FROM   (
    SELECT  H.*,
            RANK() OVER ( PARTITION BY EMPLOYEE_ID ORDER BY CREATE_DATE DESC ) AS rnk
    FROM    EMPLOYEE_HISTORY H
  )
  WHERE rnk = 1
) H
ON  H.EMPLOYEE_ID = E.EMPLOYEE_ID
使用
排名
(或
密集排名
行数
)分析功能:

SELECT 1
FROM EMPLOYEE E
JOIN   (
  SELECT *
  FROM   (
    SELECT  H.*,
            RANK() OVER ( PARTITION BY EMPLOYEE_ID ORDER BY CREATE_DATE DESC ) AS rnk
    FROM    EMPLOYEE_HISTORY H
  )
  WHERE rnk = 1
) H
ON  H.EMPLOYEE_ID = E.EMPLOYEE_ID

您能显示完整的查询吗?
中不需要
。子查询不会返回多行<代码>=
可以使用。(但这很可能对性能没有影响。)@VamsiPrabhala请参见编辑。相反,在中,使用密集等级分析功能过滤员工历史记录中的记录,然后(在更高级别上)进行连接。您可以尝试在
员工历史记录(员工id ASC,创建日期描述)上建立索引
如果
create\u date
尚未在其他索引中按降序排列。是否可以显示完整的查询?不需要在那里设置
。子查询不会返回多行<代码>=
可以使用。(但这很可能对性能没有影响。)@VamsiPrabhala请参见编辑。相反,在中,使用密集等级分析功能过滤员工历史记录中的记录,然后(在更高级别上)进行连接。您可以尝试在
员工历史记录(员工id ASC,创建日期描述)上建立索引
if
create\u date
尚未在其他索引中按降序排列。这是迄今为止成本最低的方法。排号非常昂贵。谢谢这是迄今为止成本最低的方法。排号非常昂贵。谢谢