合并来自单独表的日期字段
Combining dates fields from separate tables
我有两个几乎一模一样的table。唯一的区别是一个是存档 table(称为 B),它从另一个 table(称为 A)
中删除了任何记录
我需要获取给定数据范围内的所有记录,因此我需要加入两个 tables(实际上将它们加入第三个以获得不在那些数据中的信息) tables,但这不影响我的问题。
我想按记录的来源时间分组(即 trunc(<date_field>, 'hh')
但是,因为我需要从两个 table 中获取每小时的记录,所以我似乎需要生成一个日期字段来分组,否则分组就没有意义;每条记录只有一个字段中的日期,所以如果我按 table 的日期字段中的任何一个进行分组,它本质上会忽略另一个字段中的记录,如果我同时按两个字段分组,我将得不到任何数据,因为没有记录出现在 tables.
所以,我想做的是添加两个“日期”并让它像在 Excel 中那样工作(即日期被视为它们的等效数字,被添加,结果日期是返回,顺便说一下,这至少是添加日期有效的一种情况,despite this thread's opinion otherwise)
这更有意义,因为我将用 0 替换空日期值,因此它在功能上应该类似于将数字添加到日期 (12/31/14 + 1 = 1/1/15)。
我只是无法让它工作。我已经尝试了几次迭代以使计算工作最新的是:
SELECT DISTINCT Avg(NVL(to_number(to_char(trunc(fcr.actual_start_date, 'hh')))*86400, 0) + NVL(to_Number(to_char(trunc(acr.actual_start_date, 'hh')))*86400, 0)) Start_Num, SUM(AA.SESSIONCPU) TotalCPU, Count(1) Cnt
, SUM((NVL(to_number(to_char(trunc(fcr.actual_completion_date, 'hh')))*86400, 0) + NVL(to_Number(to_char(trunc(acr.actual_completion_date, 'hh')))*86400, 0)
- NVL(to_number(to_char(trunc(fcr.actual_start_date, 'hh')))*86400, 0) - NVL(to_Number(to_char(trunc(acr.actual_start_date, 'hh')))*86400, 0))) TotRun
FROM PSTAT.A$_A AA
LEFT OUTER JOIN APPL.FND_CR FCR On FCR.O_SES_ID = AA.SEsID
LEFT OUTER Join XX.E_FND_CR ACR on ACR.O_SES_ID = aa.sesid
WHERE (trunc(fcr.actual_start_date) >= to_date('28-Dec-2014', 'DD-MON-YYYY')
Or trunc(acr.actual_start_date) >= to_date('28-Dec-2014', 'DD-MON-YYYY'))
AND rownum <= 1048500
and (acr.status_code = 'C' or fcr.status_Code = 'C')
AND aa.sessioncpu is not null
GROUP BY to_number(NVL(trunc(fcr.actual_start_date, 'hh'), 0))*86400 + to_Number(NVL(trunc(acr.actual_start_date, 0), 'hh'))*86400
ORDER BY 2, 1;
上面代码的明显问题是 Toad 一直忽略强制转换并表示它在获取数字时期望日期值(0 突出显示)。所以如果有人可以:
A) 告诉我为什么 Toad 会忽略演员表(它应该看到一个数字,所以绝对不会期待日期)
B) 提供关于如何使添加工作的任何建议,或者如果失败建议将三个 table 组合起来的替代路线,以便我能够按开始日期值进行分组
一如既往,非常感谢您的帮助。
添加日期或将它们转换为数字抛出 ORA-00975: date+date not allowed
和 ORA-01722: invalid number
。
那么这里可以做些什么来以Excel方式对日期进行操作呢?我的想法是从您要操作的每个日期减去日历 to_date(1, J)
的第一天。
考试日期示例:
with test_data as (
select sysdate dt from dual union all
select to_date(1, 'J') from dual union all
select null from dual )
select nvl(trunc(dt, 'hh') - to_date(1, 'J'), 0) num_val, dt,
to_char(dt, 'J') tc1, to_char(dt, 'yyyy-mm-ss hh24:mi:ss') tc2
from test_data
NUM_VAL DT TC1 TC2
---------- ---------- ------- -------------------
2457105,96 2015-03-24 2457106 2015-03-14 23:12:14
0 4712-01-01 0000001 4712-01-00 00:00:00
0
@David,您的建议似乎很有用。对于那些后来出现的人,我的代码更新如下:
SELECT trunc(cr.actual_start_date, 'hh') Start_Date, SUM(AA.SESSIONCPU) TotalCPU,
Count(1) Cnt, SUM((cr.Actual_Completion_Date - cr.Actual_Start_Date)*86400) TotalRun
FROM (SELECT Actual_Start_Date, Actual_Completion_Date, Oracle_Session_ID, Status_Code
FROM APPL.FND_CR
UNION ALL
SELECT Actual_Start_Date, Actual_Completion_Date, Oracle_Session_ID, Status_Code
FROM XX.E_FND_CR) cr
RIGHT OUTER JOIN PSTAT.A$_A AA ON cr.Oracle_Session_ID = AA.SessionID
WHERE trunc(cr.actual_start_date) >= to_date('28-Dec-2014', 'DD-MON-YYYY')
AND rownum <= 1048500
and cr.status_code = 'C'
GROUP BY trunc(cr.actual_start_date, 'hh')
ORDER BY 1;
我有两个几乎一模一样的table。唯一的区别是一个是存档 table(称为 B),它从另一个 table(称为 A)
中删除了任何记录我需要获取给定数据范围内的所有记录,因此我需要加入两个 tables(实际上将它们加入第三个以获得不在那些数据中的信息) tables,但这不影响我的问题。
我想按记录的来源时间分组(即 trunc(<date_field>, 'hh')
但是,因为我需要从两个 table 中获取每小时的记录,所以我似乎需要生成一个日期字段来分组,否则分组就没有意义;每条记录只有一个字段中的日期,所以如果我按 table 的日期字段中的任何一个进行分组,它本质上会忽略另一个字段中的记录,如果我同时按两个字段分组,我将得不到任何数据,因为没有记录出现在 tables.
所以,我想做的是添加两个“日期”并让它像在 Excel 中那样工作(即日期被视为它们的等效数字,被添加,结果日期是返回,顺便说一下,这至少是添加日期有效的一种情况,despite this thread's opinion otherwise)
这更有意义,因为我将用 0 替换空日期值,因此它在功能上应该类似于将数字添加到日期 (12/31/14 + 1 = 1/1/15)。
我只是无法让它工作。我已经尝试了几次迭代以使计算工作最新的是:
SELECT DISTINCT Avg(NVL(to_number(to_char(trunc(fcr.actual_start_date, 'hh')))*86400, 0) + NVL(to_Number(to_char(trunc(acr.actual_start_date, 'hh')))*86400, 0)) Start_Num, SUM(AA.SESSIONCPU) TotalCPU, Count(1) Cnt
, SUM((NVL(to_number(to_char(trunc(fcr.actual_completion_date, 'hh')))*86400, 0) + NVL(to_Number(to_char(trunc(acr.actual_completion_date, 'hh')))*86400, 0)
- NVL(to_number(to_char(trunc(fcr.actual_start_date, 'hh')))*86400, 0) - NVL(to_Number(to_char(trunc(acr.actual_start_date, 'hh')))*86400, 0))) TotRun
FROM PSTAT.A$_A AA
LEFT OUTER JOIN APPL.FND_CR FCR On FCR.O_SES_ID = AA.SEsID
LEFT OUTER Join XX.E_FND_CR ACR on ACR.O_SES_ID = aa.sesid
WHERE (trunc(fcr.actual_start_date) >= to_date('28-Dec-2014', 'DD-MON-YYYY')
Or trunc(acr.actual_start_date) >= to_date('28-Dec-2014', 'DD-MON-YYYY'))
AND rownum <= 1048500
and (acr.status_code = 'C' or fcr.status_Code = 'C')
AND aa.sessioncpu is not null
GROUP BY to_number(NVL(trunc(fcr.actual_start_date, 'hh'), 0))*86400 + to_Number(NVL(trunc(acr.actual_start_date, 0), 'hh'))*86400
ORDER BY 2, 1;
上面代码的明显问题是 Toad 一直忽略强制转换并表示它在获取数字时期望日期值(0 突出显示)。所以如果有人可以:
A) 告诉我为什么 Toad 会忽略演员表(它应该看到一个数字,所以绝对不会期待日期)
B) 提供关于如何使添加工作的任何建议,或者如果失败建议将三个 table 组合起来的替代路线,以便我能够按开始日期值进行分组
一如既往,非常感谢您的帮助。
添加日期或将它们转换为数字抛出 ORA-00975: date+date not allowed
和 ORA-01722: invalid number
。
那么这里可以做些什么来以Excel方式对日期进行操作呢?我的想法是从您要操作的每个日期减去日历 to_date(1, J)
的第一天。
考试日期示例:
with test_data as (
select sysdate dt from dual union all
select to_date(1, 'J') from dual union all
select null from dual )
select nvl(trunc(dt, 'hh') - to_date(1, 'J'), 0) num_val, dt,
to_char(dt, 'J') tc1, to_char(dt, 'yyyy-mm-ss hh24:mi:ss') tc2
from test_data
NUM_VAL DT TC1 TC2
---------- ---------- ------- -------------------
2457105,96 2015-03-24 2457106 2015-03-14 23:12:14
0 4712-01-01 0000001 4712-01-00 00:00:00
0
@David,您的建议似乎很有用。对于那些后来出现的人,我的代码更新如下:
SELECT trunc(cr.actual_start_date, 'hh') Start_Date, SUM(AA.SESSIONCPU) TotalCPU,
Count(1) Cnt, SUM((cr.Actual_Completion_Date - cr.Actual_Start_Date)*86400) TotalRun
FROM (SELECT Actual_Start_Date, Actual_Completion_Date, Oracle_Session_ID, Status_Code
FROM APPL.FND_CR
UNION ALL
SELECT Actual_Start_Date, Actual_Completion_Date, Oracle_Session_ID, Status_Code
FROM XX.E_FND_CR) cr
RIGHT OUTER JOIN PSTAT.A$_A AA ON cr.Oracle_Session_ID = AA.SessionID
WHERE trunc(cr.actual_start_date) >= to_date('28-Dec-2014', 'DD-MON-YYYY')
AND rownum <= 1048500
and cr.status_code = 'C'
GROUP BY trunc(cr.actual_start_date, 'hh')
ORDER BY 1;