oracle CONNECT BY函数不适用于DATE数据类型的列?

pinkon5k  于 2022-12-03  发布在  Oracle
关注(0)|答案(1)|浏览(143)

我尝试使用connectbyprior和connectbyroot函数来构建另一个表的表(ORACLE),这样我就有了一个表,其中显示了所有员工及其经理,还显示了经理的经理到ceo(因此,如果该雇员在层次结构中有5个经理在他之上,则有5行用于该雇员)。作为更大的CTE的一部分,它工作得很好。然而,现在,我想包含基表中的日期列。
基表类似于:
| 雇员ID|员工姓名|管理员ID|管理器Name|日期列|
| - -|- -|- -|- -|- -|
| 小行星12345|米勒|小行星45454|霍金斯|2021年2月21日|
现在,我将使用此基表创建一个新表:

SELECT distinct employeeID, employeeName, managerName, CONNECT_BY_ROOT managerID as managerID
FROM basetable
CONNECT BY PRIOR employeeID = managerID

现在,这工作得非常好,我得到了我预期的结果(负载〈1秒)。
然而,当我包含dateColumn(数据类型:DATE)里面选择,它不会停止加载(我等了40分钟),为什么是这种情况?
编辑:根据MT()的要求,提供了一些详细信息:
这是我尝试使用的CTE。没有dateColumn,它工作正常。

insert into targettable(EMP_ID, EMP_FORENAME, EMP_SURNAME, MGR_SURNAME, MGR_ID, date_Column)
with employees as (
select employeeID,
       employeeForename,
       employeeSurname,
       managerName,
       managerID,
       trunc(dateColumn) as dateColumn
from basetable
where employeeSurname is not null
),
hierarchy as (
SELECT distinct employeeID,
       employeeForename,
       employeeSurname,
       managerName,
       CONNECT_BY_ROOT managerID as managerID,
       trunc(dateColumn) as dateColumn
FROM employees e1
CONNECT BY PRIOR employeeID = managerID
),
base as (
select distinct e1.employeeID, e1.employeeForename, e1.employeeSurname, e2.employeeForename || ' ' || e2.employeeSurname managerName, e1.managerID, trunc(e1.dateColumn) as dateColumn
from hierarchy e1
left join employees e2 on e1.managerID = e2.employeeID)
select *
from base
where managerID is not null;
kognpnkq

kognpnkq1#

一个原因可能是,在Oracle中,DATE数据类型是一种二进制数据类型,由7个字节组成,分别表示世纪、世纪年份、月、日、小时、分钟和秒。它始终具有这7个组成部分,并且从不以任何特定的人类可读格式存储。
当您显示结果时,您的客户端应用程序似乎默认为仅显示世纪到日组件,而不显示小时到秒组件;然而那些组件仍然存在。
因此,当您执行以下操作时:

SELECT distinct
       employeeID,
       employeeName,
       managerName,
       CONNECT_BY_ROOT managerID as managerID,
       dateColumn
FROM   basetable
CONNECT BY PRIOR employeeID = managerID

您在dateColumn中将DISTINCT值的精确度降低到秒,但只显示精确到天的值。这意味着您可能会返回比预期大得多的数据集,性能问题可能是因为您不是为唯一的雇员和日期加载100行,而是加载100,000行。000行,这将花费更多的时间。
您可以尝试TRUNC将日期回溯到午夜:

SELECT distinct
       employeeID,
       employeeName,
       managerName,
       CONNECT_BY_ROOT managerID as managerID,
       TRUNC(dateColumn) AS dateColumn
FROM   basetable
CONNECT BY PRIOR employeeID = managerID

相关问题